результаты wc как переменные

Я хотел бы использовать строки, поступающие из " wc " в качестве переменных. Например:

echo 'foo bar' > file.txt
echo 'blah blah blah' >> file.txt
wc file.txt

2  5 23 file.txt

Я хотел бы иметь что-то вроде $lines, $words и $characters связанные со значениями 2, 5 и 23. Как я могу сделать это в bash?

6 ответов


есть и другие решения, но простой, который я обычно использую, чтобы поставить выход wc во временном файле, а затем прочитайте оттуда:

wc file.txt > xxx
read lines words characters filename < xxx 
echo "lines=$lines words=$words characters=$characters filename=$filename"
lines=2 words=5 characters=23 filename=file.txt

преимущество этого метода заключается в том, что вам не нужно создавать несколько awk процессы, по одному для каждой переменной. Недостатком является то, что вам нужен временный файл, который необходимо потом удалить.

будьте осторожны: это не работает:

wc file.txt | read lines words characters filename

проблема в том, что трубопроводы read создает другой процесс, и переменные обновляются там, поэтому они недоступны в вызывающей оболочке.

Edit: добавление решения по arnaud576875:

read lines words chars filename <<< $(wc x)

работает без записи в файл (и не имеет проблемы с трубой). Это специфично для bash.

из руководства bash:

Here Strings

   A variant of here documents, the format is:

          <<<word

   The word is expanded and supplied to the command on its standard input.

ключ-это бит" слово расширено".


в чистом Баш: (нет awk)

a=($(wc file.txt))
lines=${a[0]}
words=${a[1]}
chars=${a[2]}

это работает с использованием массивов bash. a=(1 2 3) создает массив с элементами 1, 2 и 3. Тогда мы можем получить доступ к отдельным элементам с ${a[indice]} синтаксис.

альтернатива: (на основе решения gonvaled)

read lines words chars <<< $(wc x)

или в sh:

a=$(wc file.txt)
lines=$(echo $a|cut -d' ' -f1)
words=$(echo $a|cut -d' ' -f2)
chars=$(echo $a|cut -d' ' -f3)

просто добавить другой вариант --

set -- `wc file.txt`
chars=
words=
lines=

это очевидно clobbers $* и связанные переменные. В отличие от некоторых других решений здесь, он переносится на другие оболочки Борна.


lines=`wc file.txt | awk '{print }'`
words=`wc file.txt | awk '{print }'`
...

вы также можете в магазине wc результат в первую очередь.. а потом разобрать.. если вы придирчивы к производительности:)


вы можете назначить выход переменной, открыв sub shell:

$ x=$(wc some-file)
$ echo $x
1 6 60 some-file

Теперь, чтобы получить отдельные переменные, самый простой вариант-использовать awk:

$ x=$(wc some-file | awk '{print }')
$ echo $x
1

declare -a result
result=( $(wc < file.txt) )
lines=${result[0]}
words=${result[1]}
characters=${result[2]}
echo "Lines: $lines, Words: $words, Characters: $characters"