Saya ingin menghapus semua spasi dan tab depan dan belakang dari setiap baris dalam output.
Apakah ada alat sederhana seperti trim
saya dapat menyalurkan output saya ke?
File contoh:
test space at back
test space at front
TAB at end
TAB at front
sequence of some space in the middle
some empty lines with differing TABS and spaces:
test space at both ends
Jawaban:
atau lebih pendek:
Akan memangkas spasi awal dan akhir karakter tab 1 dan juga memeras urutan tab dan spasi menjadi satu ruang.
Itu bekerja karena ketika Anda menetapkan sesuatu ke salah satu bidang ,
awk
membangun kembali seluruh catatan (seperti yang dicetak olehprint
) dengan bergabung dengan semua bidang ($1
, ...,$NF
) denganOFS
(ruang pada pengaturan standar).1 (dan mungkin karakter kosong lainnya tergantung pada lokal dan
awk
implementasinya)sumber
awk '{$1=$1}1'
;
ini diperlukan dalam sintaks awk standarecho -e 'foo \t bar' | awk '{$1=$1};1'
echo ' hello ' | xargs
Perintah dapat diringkas seperti itu jika Anda menggunakan GNU
sed
:Contoh
Inilah perintah di atas dalam aksi.
Anda dapat menggunakan
hexdump
untuk mengonfirmasi bahwased
perintah tersebut menghapus karakter yang diinginkan dengan benar.Kelas karakter
Anda juga dapat menggunakan nama kelas karakter alih-alih mendaftar secara himpunan set seperti ini
[ \t]
,:Contoh
Sebagian besar alat GNU yang menggunakan ekspresi reguler (regex) mendukung kelas-kelas ini.
Menggunakan ini alih-alih set literal selalu tampak seperti buang-buang ruang, tetapi jika Anda khawatir dengan kode Anda yang portabel, atau harus berurusan dengan set karakter alternatif (pikirkan internasional), maka Anda mungkin ingin menggunakan nama kelas sebagai gantinya.
Referensi
sumber
[[:space:]]
tidak setara dengan[ \t]
dalam kasus umum (unicode, dll).[[:space:]]
mungkin akan jauh lebih lambat (karena ada lebih banyak jenis spasi putih di unicode daripada adil' '
dan'\t'
). Hal yang sama untuk yang lainnya.sed 's/^[ \t]*//'
tidak portabel. Pada dasarnya POSIX bahkan mengharuskan untuk menghapus urutan ruang, garis miring terbalik ataut
karakter, dan itulah yang dilakukan GNUsed
ketikaPOSIXLY_CORRECT
berada di lingkungan.sed 's/^[[:blank:]]*//;s/[[:blank:]]*$//'
Seperti yang disarankan oleh Stéphane Chazelas dalam jawaban yang diterima, Anda sekarang dapat
membuat skrip
/usr/local/bin/trim
:dan berikan file itu hak yang dapat dieksekusi:
Sekarang Anda dapat meneruskan setiap output ke
trim
misalnya:(untuk komentar di bawah ini: saya menggunakan ini sebelumnya:
while read i; do echo "$i"; done
yang juga berfungsi dengan baik, tetapi kurang performan)
sumber
while read -r line
untuk melestarikan backslashes dan bahkan kemudian ... . Mengenai file / kecepatan besar, sungguh, Anda memilih solusi terburuk. Saya tidak berpikir ada yang lebih buruk di luar sana. Lihat jawaban pada Mengapa menggunakan shell loop untuk memproses teks praktik buruk? termasuk komentar saya pada jawaban terakhir tempat saya menambahkan tautan ke tolok ukur kecepatan. Thesed
jawaban di sini adalah baik-baik saja IMO dan jauh lebih baik daripadaread
.-
dan diikuti oleh kombinasi 1 atau lebih e, E atau n karakter, dan / atau berisi karakter NUL. Selain itu, baris yang tidak diakhiri setelah baris baru terakhir akan dilewati.xargs tanpa argumen melakukannya.
Contoh:
sumber
xargs
akan gagal memberikan jika input berisi garis miring terbalik dan tanda kutip tunggal.echo
doa. Beberapa implementasi gema juga akan memproses opsi dan / atau garis miring terbalik ... Itu juga hanya berfungsi untuk input baris tunggal.Jika Anda membaca baris ke variabel shell,
read
lakukan itu kecuali diinstruksikan sebaliknya .sumber
read
. Jadi, jika Anda pipa sambil membacanya berfungsi:cat file | while read i; do echo $i; done
echo "$i"
untuk melihat efek sebenarnya dariread
Jika Anda menyimpan baris sebagai variabel, Anda dapat menggunakan bash untuk melakukan pekerjaan:
hapus spasi putih terkemuka dari string:
hapus spasi kosong dari string:
hapus semua spasi putih dari string:
sumber
Untuk menghapus semua spasi awal dan akhir dari garis tertentu berkat alat 'pipa', saya dapat mengidentifikasi 3 cara berbeda yang tidak sepenuhnya sama. Perbedaan-perbedaan ini menyangkut ruang antara kata-kata dari garis input. Bergantung pada perilaku yang diharapkan, Anda akan menentukan pilihan.
Contohnya
Untuk menjelaskan perbedaannya, mari pertimbangkan jalur input dummy ini:
tr
tr
benar-benar perintah sederhana. Dalam hal ini, ia menghapus spasi atau karakter tabulasi.awk
awk
menghapus spasi terdepan dan tailing dan menekan ke satu spasi setiap spasi di antara kata-kata.sed
Dalam hal ini,
sed
hapus spasi di depan dan di belakang tanpa menyentuh spasi di antara kata-kata.Ucapan:
Dalam hal satu kata per baris,
tr
lakukan pekerjaan.sumber
[:space:]
, alih-alih [: kosong:], untuk perintahtr
, seperti :,... | tr -d [:space:]
untuk menghapus baris baru juga. (lihat:man tr
)sed adalah alat yang bagus untuk itu:
Anda dapat menggunakannya untuk kasing Anda baik dalam teks, mis
atau dengan bertindak sesuai 'inline' jika Anda
sed
adalah GNU:tetapi mengubah sumber dengan cara ini "berbahaya" karena mungkin tidak dapat dipulihkan ketika tidak berfungsi dengan benar (atau bahkan ketika itu benar!), jadi backup terlebih dahulu (atau gunakan
-i.bak
yang juga memiliki manfaat menjadi portabel untuk beberapa BSDsed
) !sumber
Perintah menerjemahkan akan bekerja
sumber
Jika string yang hendak dipotong pendek dan kontinu / berdekatan, seseorang dapat dengan mudah memberikannya sebagai parameter untuk fungsi bash:
sumber