отримати просто ціле число від wc в bash


115

Чи є спосіб отримати ціле число, яке wc повертає в bash?

В основному я хочу записати номери рядків і кількість слів на екрані після імені файлу.

output: filename linecount wordcount Ось що я маю досі:

files=`ls`
for f in $files;
do
        if [ ! -d $f ] #only print out information about files !directories
        then
                # some way of getting the wc integers into shell variables and then printing them
                echo "$f $lines $ words"
        fi
done

Відповіді:


57

Ви можете скористатися cutкомандою, щоб отримати лише перше слово wcвиводу 's (яке є рядком або кількістю слів):

lines=`wc -l $f | cut -f1 -d' '`
words=`wc -w $f | cut -f1 -d' '`

5
Запуск wc двічі для одного файлу неефективний.
gawi

3
Щоправда, тому я вважаю, що відповідь Джеймса Броудхеда набагато краща. Мені не cutвдалося попрацювати над повним результатом, wc $fоскільки кількість пробілів між полями змінюється.
casablanca

1
@casablanca Ви можете видавити кількість пробілів за допомогою 'tr -s'. Я перерахував більше портативних рішень цього питання у своїй відповіді нижче.
рубль

Оскільки у цій відповіді, яку ми призначаємо до змінної, ми могли вбити пробіли за допомогою
cycollins

88

Найпростіша відповідь коли-небудь:

wc < filename 

5
Але не дає бажаного результату.
Дейв Ньютон

Ви впевнені, що це так, ви просто переходите в ті параметри, які ви б у будь-якому випадку. наприклад, якщо ви це зробите wc -c < file name, це дасть вам лише цілу кількість байтів і більше нічого.
BananaNeil

13
Моя думка полягала в тому, що якщо ви збираєтесь відповісти на питання (1,5 року), ви можете також поставити всю інформацію у відповідь, це все :)
Дейв Ньютон,

ой, просто перечитав питання .. #fail, я досліджував, як отримати лише цілі числа, і я використовував інформацію з однієї з відповідей, коли я виявив кращу відповідь, а потім вирішив опублікувати про це. вибачте ..
BananaNeil

3
Ви відповіли Google, ось що враховується. :-)
Ciro Santilli 郝海东 冠状 病 六四 事件

82

Просто:

wc -l < file_name

зробить роботу. Але цей вихід включає в себе попередньо встановлений пробіл у міру wcправої вирівнювання числа.


3
Щоб отримати лише кількість рядків без пробілів: wc -l < foo.txt | xargsref - stackoverflow.com/a/12973694/149428
Тейлор

1
Таким чином, поки команда створює відповідь з провідними пробілами, запитуючий призначав змінну, яка автоматично відкидає провідні пробіли (принаймні, такий був мій досвід роботи в старшій базі OSX). Іншими словами, lines=`wc -l < $f`виходить змінна "лінія", значення якої не має провідних пробілів.
cycollins

Що робити, якщо я працюю з find? Я отримую помилку: find . -path -prune -o -name "*.swift" -print0 | xargs -0 wc -lпрацює добре, але друкує кожен файл. Якщо я використовую, find . -path -prune -o -name "*.swift" -print0 | xargs -0 wc -l <я отримую помилку. parse error near '\n'
Nuno Gonçalves

55
wc $file | awk {'print "$4" "$2" "$1"'}

Відрегулюйте у міру необхідності для вашого плану.

Також приємніше використовувати позитивну логіку ("це файл") над негативною ("не каталог")

[ -f $file ] && wc $file | awk {'print "$4" "$2" "$1"'}

1
У моєму Windows в Cmder (bash 4.4.12) це працює: wc $file | awk '{print $4" "$2" "$1}'- апострофи поза межами {}.
Grzegorz Gierlik

36

Іноді wc виводить у різних форматах на різних платформах. Наприклад:

В ОС X:

$ echo aa | wc -l

         1

У Centos:

$ echo aa | wc -l

1

Тож використання лише розрізання може не отримати номер. Замість цього спробуйте tr видалити пробіли:

$ echo aa | wc -l | tr -d ' '

23

Прийняті / популярні відповіді не працюють на OSX.

Будь-яке з наведеного нижче має бути переносним на bsd та linux.

wc -l < "$f" | tr -d ' '

АБО

wc -l "$f" | tr -s ' ' | cut -d ' ' -f 2

АБО

wc -l "$f" | awk '{print $1}'

11

Якщо ви переймете ім'я файлу в wcнього, воно не виводить ім'я файлу на виході.

Bash:

read lines words characters <<< $(wc < filename)

або

read lines words characters <<EOF
$(wc < filename)
EOF

Замість того, forщоб використовувати ітерацію над результатом ls, зробіть це:

for f in *

яка працюватиме, якщо є імена файлів, які містять пробіли.

Якщо ви не можете використовувати глобус, вам слід передати трубку в while readцикл:

find ... | while read -r f

або використовувати процес заміщення

while read -r f
do
    something
done < <(find ...)

Я все-таки звернувся до вас, але вам не потрібно перенаправляти ім’я файлу. Просто зафіксуйте його як додаткове поле. read lines words characters filename <<< $(wc "$f")О, і якщо ви використовували * для загартовування проти пробілів, ви також хочете подвоїти процитування вар при використанні.
Бруно Броноський

Використання додаткової змінної - це справді інший спосіб зробити це, але якщо ви не збираєтеся використовувати цю змінну (можливо, ви вже маєте ім'я файлу в змінній - $fу цьому випадку), це зайве. Також ОП запитав, як отримати просто ціле число. Ви вірно ставитесь до цитування змінної, але я не показав використання змінної, тому пропустив згадку про цю точку. for f in *Форма повинна бути майже завжди використовується замість того , щоб використовувати вихід ls, як ви знаєте.
Призупинено до подальшого повідомлення.

Я повністю згоден у цьому ls. Це отримає вам нагороду. partmaps.org/era/unix/award.html#ls
Бруно Броноскі

Якщо ви не хочете імені файлу, ви можете зробити це:read lines words characters _ <<< $(wc "$f")

@EvanTeitelman: Як обговорювалося в парі коментарів вище вашого. $_це лише інша змінна.
Призупинено до подальшого повідомлення.

3

Якщо файл невеликий, ви можете дозволити собі дзвонити wcдвічі та використовувати щось на кшталт наступного, що дозволяє уникнути перетворення додаткового процесу:

lines=$((`wc -l "$f"`))
words=$((`wc -w "$f"`))

$((...))Є арифметика розширення Баша. У wcцьому випадку це видаляє будь-який пробіл з виводу .

Це рішення має більше сенсу, якщо вам потрібен або рядок рядків, або слово .





0

Спробуйте це:

wc `ls` | awk '{ LINE += $1; WC += $2 } END { print "lines: " LINE  " words: " WC }'

Він створює кількість рядків та кількість слів (LINE та WC) та збільшує їх за значеннями, витягнутими з wc (використовуючи $ 1 за значення першого стовпця та 2 $ для другого) і, нарешті, друкує результати.


0

"В основному я хочу записати номери рядків і кількість слів на екрані після імені файлу."

answer=(`wc $f`)
echo -e"${answer[3]}
lines:  ${answer[0]}
words:  ${answer[1]}
bytes:  ${answer[2]}"

Виводи: рядки myfile.txt: 10 слів: 20 байт: 120


0
files=`ls`
echo "$files" | wc -l | perl -pe "s#^\s+##"

Якщо ви все perlодно користуєтесь , можливо, також підрахунок слів у Perl. Більш економічний підхід буде трубаtr -d '[:space:]'
tripleee
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.