Terminals:
Shells:
Other tips:
VAR=0 ls -1 | while read file do [ "$file" = "tmp" ] && VAR=1 done echo $VAR # It turns out that $VAR is always zero here
echo "tmp.txt" | read file
while
loop consumes the input from the pipe, it is launched in a subshell, thus all changes to the variables inside the loop do not work as expected (are not propagated to calling shell). Solution: loop should be executed by primary shell:VAR=0 while read file do [ "$file" = "tmp" ] && VAR=1 done < <(ls -1)
Process substitution which is used in above example, is described here. Another good application of process substitution is capturing the exit code of first command in a pipe:
if mount /dev/sda /mnt 2> >(head -1) then ... fi
The same way read
and arrayread
when applied after the pipe initialize the variable in a forked shell (hence echo file.txt | read line
does not work) so the solution looks this:
read file < <(echo file.txt)
VAR=0 for file in $(ls -1) do [ "$file" = "tmp" ] && VAR=1 done
cat 1.txt 2.txt | sort | uniq -d
comm -12 1.txt 2.txt
Symmetric difference of two lists:
cat 1.txt 2.txt | sort | uniq -u
( >&2 echo "bla-bla" );
echo "bla-bla" > /dev/stderr
... | tee /dev/stderr | ...
read -r -d '' SCRIPT <<'EOS' use strict; my $lines = 0; while (<>) { chomp; $files++; } print "Number of lines: $lines\n"; EOS perl -e "$SCRIPT"
... | tail -n +2
while IFS= read -r line do echo "$line" done < some_file.txt
Similarly to read the whole file into variable:
IFS= FILE=`cat some_file`
( echo -e "File\tMD5\tSize\tCTime" find . -type f -printf '%p\t%s\t%T+\n' | sort -k1 -t$'\t' | while IFS= read -r line do echo -e "$(md5sum "`echo "$line" | cut -f1`" | cut -f1 -d' ')\t$line"; \ done ) | column -t -s $'\t'
See also:
xargs
? xargs
should be tweaked, but if the list is produced by find
then solutions are:find ... -print0 | xargs -0 wc -l
find
ability to append arguments: find ... -exec wc -l {} +
seq 1 10 | paste -s -d+ | bc
$ cat file | tr -d -c '#' | wc -c
if [[ $fullpath == *.txt ]] then echo "This is text file" fi
file=`basename "$fullpath"` extension=${file##*.} filename=${file%.*}
array=( "${array[@]/#/prefix_}" ) array=( "${array[@]/%/_suffix}" )
To print an array as new-line separated string:
IFS=$'\n' echo "${array[*]}" IFS=$'\n' echo "$*" | xargs ...
tr -dc A-Za-z0-9 < /dev/urandom | fold -w 16 | head -5
$ myprog # press Ctrl+Z to suspend the program $ bg $ disown # switch to another terminal / screen / tmux session $ reptyr $(pgrep myprog)
~/.bashrc
:set bell-style none
However bell can be useful to notify long running task:
tee
utility.
stdbuf
utility:
stdbuf -oL tail -f /var/log/messages | tee logs.txt
"Девица не хочет лезть в Окно" – device not compatible with Windows.