dapatkan hanya integer dari wc di bash

115

Apakah ada cara untuk mendapatkan integer yang wc dikembalikan dalam bash?

Pada dasarnya saya ingin menulis nomor baris dan jumlah kata ke layar setelah nama file.

output: filename linecount wordcount Inilah yang saya miliki sejauh ini:

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

Yordania
sumber

Jawaban:

57

Anda dapat menggunakan cutperintah untuk mendapatkan hanya kata pertama dari wckeluaran (yaitu jumlah baris atau kata):

lines=`wc -l $f | cut -f1 -d' '`
words=`wc -w $f | cut -f1 -d' '`
casablanca
sumber
5
Menjalankan wc dua kali untuk file yang sama tidak efisien.
gawi
3
Benar, itulah mengapa saya pikir jawaban James Broadhead jauh lebih baik. Saya tidak bisa cutmengerjakan hasil penuh wc $fkarena jumlah spasi antar bidang bervariasi.
casablanca
1
@casablanca Anda dapat menekan jumlah spasi menggunakan 'tr -s'. Saya telah membuat daftar solusi yang lebih portabel untuk pertanyaan ini dalam jawaban saya di bawah ini.
rubel
Karena dalam jawaban ini kami menetapkan ke variabel, kami dapat mematikan spasi dengan
cycollins
88

Jawaban paling sederhana yang pernah ada:

wc < filename 
BananaNeil
sumber
5
Tetapi tidak menghasilkan keluaran yang diinginkan.
Dave Newton
tentu saja demikian, Anda cukup memasukkan parameter yang sesuai yang Anda inginkan. misalnya, jika Anda melakukannya wc -c < file name, itu hanya akan memberi Anda bilangan bulat byte dan tidak ada yang lain.
BananaNeil
13
Maksud saya adalah bahwa jika Anda akan menjawab pertanyaan (1,5 tahun), sebaiknya Anda memasukkan semua info ke dalam jawabannya, itu saja :)
Dave Newton
whoops, hanya membaca kembali pertanyaan .. # FAIL, saya sedang meneliti bagaimana untuk mendapatkan hanya bilangan bulat, dan saya menggunakan informasi dari salah satu jawaban, ketika saya menemukan jawaban yang lebih baik, dan kemudian memutuskan untuk posting tentang hal itu. maaf ..
BananaNeil
3
Anda telah menjawab Google, itulah yang terpenting. :-)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
82

Hanya:

wc -l < file_name

akan melakukan pekerjaan itu. Tapi keluaran ini menyertakan spasi kosong sebagai wcangka rata kanan.

sten
sumber
3
Untuk mendapatkan hitungan baris saja tanpa spasi: wc -l < foo.txt | xargsref - stackoverflow.com/a/12973694/149428
Taylor Edmiston
1
Jadi, sementara perintah menghasilkan jawaban dengan spasi di depan, penanya menetapkan ke variabel dan itu menghilangkan spasi di depan secara otomatis (setidaknya itu adalah pengalaman saya pada pesta OSX yang lebih lama). Dengan kata lain, lines=`wc -l < $f`menghasilkan variabel "baris" yang nilainya tidak memiliki spasi di depan.
cycollin
Bagaimana jika saya bergabung dengan find? Saya mendapatkan kesalahan: find . -path -prune -o -name "*.swift" -print0 | xargs -0 wc -lberfungsi dengan baik tetapi mencetak setiap file. Jika saya menggunakan find . -path -prune -o -name "*.swift" -print0 | xargs -0 wc -l <saya mendapatkan kesalahan. parse error near '\n'
Nuno Gonçalves
55
wc $file | awk {'print "$4" "$2" "$1"'}

Sesuaikan seperlunya untuk tata letak Anda.

Juga lebih baik menggunakan logika positif ("adalah file") daripada negatif ("bukan direktori")

[ -f $file ] && wc $file | awk {'print "$4" "$2" "$1"'}
James Broadhead
sumber
1
Di Windows saya di Cmder (bash 4.4.12) ini berfungsi: wc $file | awk '{print $4" "$2" "$1}'- apostrof di luar {}.
Grzegorz Gierlik
36

Terkadang output wc dalam format berbeda di platform berbeda. Sebagai contoh:

Di OS X:

$ echo aa | wc -l

         1

Di Centos:

$ echo aa | wc -l

1

Jadi menggunakan hanya potongan tidak dapat mengambil nomor tersebut. Sebagai gantinya coba tr untuk menghapus karakter spasi:

$ echo aa | wc -l | tr -d ' '
Tahsin Turkoz
sumber
23

Jawaban yang diterima / populer tidak berfungsi di OSX.

Salah satu dari berikut ini harus portabel di bsd dan linux.

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

ATAU

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

ATAU

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

Jika Anda mengarahkan nama file ke wcdalamnya menghilangkan nama file pada output.

Pesta:

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

atau

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

Alih-alih menggunakan foruntuk mengulangi keluaran ls, lakukan ini:

for f in *

yang akan berfungsi jika ada nama file yang menyertakan spasi.

Jika Anda tidak dapat menggunakan globbing, Anda harus menyalurkan ke while readloop:

find ... | while read -r f

atau gunakan substitusi proses

while read -r f
do
    something
done < <(find ...)
Dijeda sampai pemberitahuan lebih lanjut.
sumber
Saya tetap memberi suara positif kepada Anda, tetapi Anda tidak perlu mengalihkan nama file. Tangkap saja sebagai bidang tambahan. read lines words characters filename <<< $(wc "$f")Oh, dan jika Anda dulu * dikeraskan dengan spasi, Anda juga ingin mengutip ganda var saat menggunakannya.
Bruno Bronosky
Menggunakan variabel tambahan memang cara lain untuk melakukannya, tetapi jika Anda tidak akan menggunakan variabel (mungkin Anda sudah memiliki nama file dalam variabel - $fdalam hal ini), itu tidak perlu. Juga, OP meminta bagaimana untuk mendapatkan hanya integer. Anda benar tentang mengutip variabel, tetapi saya tidak menunjukkan penggunaan variabel, jadi saya menghilangkan penyebutan hal itu. The for f in *Bentuk harus hampir selalu digunakan daripada menggunakan output dari ls, seperti yang Anda tahu.
Dijeda sampai pemberitahuan lebih lanjut.
Saya setuju sepenuhnya tentang hal lsitu. Itu akan memberimu penghargaan. partmaps.org/era/unix/award.html#ls
Bruno Bronosky
Jika Anda tidak menginginkan nama file, Anda dapat melakukan ini:read lines words characters _ <<< $(wc "$f")
@EvanTeitelman: Seperti yang dibahas dalam beberapa komentar di atas milik Anda. $_hanyalah variabel yang berbeda.
Dijeda sampai pemberitahuan lebih lanjut.
3

Jika filenya kecil, Anda dapat menelepon wcdua kali, dan menggunakan sesuatu seperti berikut, yang menghindari menyalurkan ke proses tambahan:

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

Itu $((...))adalah Ekspansi Aritmatika dari bash. Ini menghapus spasi apa pun dari output wcdalam kasus ini.

Solusi ini lebih masuk akal jika Anda perlu baik yang linecount atau wordcount tersebut.

Walter Tross
sumber
2

Bagaimana dengan sed?

wc -l /path/to/file.ext | sed 's/ *\([0-9]* \).*/\1/'
mgold
sumber
1
typeset -i a=$(wc -l fileName.dat  | xargs echo | cut -d' ' -f1)
GeorgesMakarios
sumber
1

Coba ini untuk hasil numerik:
nlines = $ (wc -l <$ myfile)

paulonki
sumber
0

Coba ini:

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

Ini membuat jumlah baris, dan jumlah kata (LINE dan WC), dan meningkatkannya dengan nilai yang diekstrak dari wc (menggunakan $ 1 untuk nilai kolom pertama dan $ 2 untuk yang kedua) dan akhirnya mencetak hasilnya.

Aif
sumber
0

"Pada dasarnya saya ingin menulis nomor baris dan jumlah kata ke layar setelah nama file."

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

Keluaran: baris myfile.txt: 10 kata: 20 byte: 120

pengguna8155253
sumber
0
files=`ls`
echo "$files" | wc -l | perl -pe "s#^\s+##"
Pedro Reis
sumber
Jika Anda perltetap menggunakannya , sebaiknya lakukan penghitungan kata di Perl juga. Pendekatan yang lebih ekonomis adalah dengan menyalurkan ketr -d '[:space:]'
tripleee