Подтвердить что ты не робот

Результаты 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?

4b9b3361

Ответ 1

Существуют и другие решения, но простой, который я обычно использую, заключается в том, чтобы поместить вывод 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

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

Изменить: добавление решения 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.

Ключом является бит "word extended".

Ответ 2

В чистом bash: (нет 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)

Ответ 3

Просто добавьте еще один вариант -

set -- `wc file.txt`
chars=$1
words=$2
lines=$3

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

Ответ 4

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

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

Ответ 5

Вы можете назначить вывод переменной, открыв подклассу:

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

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

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

Ответ 6

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