Saya memiliki dua file paralel dengan jumlah baris yang sama dalam dua bahasa dan berencana untuk menggabungkan kedua file ini baris demi baris dengan pembatas |||
. Misalnya, kedua file tersebut adalah sebagai berikut:
File A:
1Mo 1,1 I love you.
1Mo 1,2 I like you.
Hi 1,3 I am hungry.
Hi 1,4 I am foolish.
File B:
1Mo 1,1 Ich liebe dich.
1Mo 1,2 Ich mag dich.
Hi 1,3 Ich habe Durst.
Hi 1,4 Ich bin neu.
Output yang diharapkan adalah seperti ini:
1Mo 1,1 I love you. ||| 1Mo 1,1 Ich liebe dich.
1Mo 1,2 I like you. ||| 1Mo 1,2 Ich mag dich.
Hi 1,3 I am hungry. ||| Hi 1,3 Ich habe Durst.
Hi 1,4 I am foolish. ||| Hi 1,4 Ich bin neu.
Saya mencoba paste
perintah seperti:
paste -d "|||" fileA fileB
Tetapi output yang dikembalikan hanya mengandung satu pipa seperti:
1Mo 1,1 I love you. |1Mo 1,1 Ich liebe dich.
1Mo 1,2 I like you. |1Mo 1,2 Ich mag dich.
Apakah ada cara untuk memisahkan setiap pasangan garis dengan pipa babat |||
?
text-processing
sed
awk
Mengerut
sumber
sumber
paste -d '|||' fileA - - fileB < /dev/null
Jawaban:
Dengan tempel POSIX :
paste
akan menggabungkan baris yang sesuai dari semua file input. Di sini kita memiliki enam filefileA
,, empat file dummy dari standar dalam-
, danfileB
.Daftar pembatas termasuk spasi, tiga pipa dan spasi dalam urutan yang akan digunakan secara
paste
melingkar.Untuk baris pertama dari enam file,
fileA
akan digabungkan dengan file dummy pertama (yang bukan apa-apa, terima kasih kepada no-op: operator), menghasilkanline1-fileA<space>
.File dummy pertama akan digabungkan dengan yang kedua dengan pipa, menghasilkan
line1-fileA |
, kemudian file dummy kedua dengan file dummy ketiga, menghasilkanline1-fileA ||
, file dummy ketiga dengan file dummy keempat, menghasilkanline1-fileA |||
.Dan file dummy keempat dengan
fileB
, menghasilkanline1-fileA ||| line1-fileB
.Langkah-langkah itu akan diulang untuk semua lini, memberi Anda hasil yang diharapkan.
Penggunaannya
:|
adalah untuk mengetik kurang, dan terutama digunakan dalam shell interaktif. Dalam skrip, Anda harus menggunakan:untuk mencegah subshell dari yang melahirkan.
sumber
:|
. alternatif cerdas untuk</dev/null
- - - -
, tetapi lain kali Anda bahkan dapat menulis beberapa baris untuk penjelasan :):|paste -d '|' fileA - - fileB
memberikan versi yang lebih benar tanpa pembatas ruang.Yah, ini tidak menggunakan sed, awk, atau grep, tetapi Anda dapat melakukannya dengan cukup mudah di bash. Perintahnya adalah:
Masalah dengan paste adalah pembatas adalah karakter tunggal. Anda juga bisa memasukkan satu karakter dan menggunakan sed untuk mengubahnya, tetapi itu akan menjadi jenis kesalahan-rawan jika karakter sudah muncul di file input.
sumber
IFS=
sebelum masing-masingread
. Anda dapat melakukannya dengan mudahpaste
. Lihat jawaban saya , dan juga yang ini untuk melihat mengapa harus menghindari menggunakanwhile
loop di skrip shell.Versi awk (GNU)
Dengan
getline
perintah diawk
, Anda dapat mengatur$0
(semua variabel untuk kolom) dari catatan input berikutnya, jikagetline < "filename"
Anda mengatur berikutnya$0
dari file yang ditentukan.Mengapa upaya Anda tidak berhasil seperti yang Anda harapkan? Dari
man paste
kita bisa membacatetapi menggunakan pembatas satu untuk setiap kolom .
Jadi perintah
paste -d '|*|*' fileA fileB fileA fileB
memberi saya garisSebuah
sed
solusi yang saya sarankan untuk menghindari bahkan jika dekat dengan upaya asli Anda, karena patch perilaku yang diperoleh untuk tujuan awal Anda:Untuk menghindari karena Anda mengganti setiap pola
|
dengan yang baru|||
, tetapi Anda harus mengasumsikan bahwa simbol pipa (|
) tidak ada dalam data Anda , kalau tidak Anda harus berurusan dengan kasus khusus dan membuat kode yang lebih kompleks untuk menghindari efek samping.Varian dengan konstruk Here String [ 1 ]
<<<
Anda menetapkan 5 pembatas dengan
-d ' ||| '
(spasi, |, |, |, spasi) dan 4 file dummy (- - - -
) yang akan mengambil data dari string kosong''
.Diuji pada GNU Awk 4.0.1, tempel (GNU coreutils) 8.21 dan sed (GNU sed) 4.2.2
sumber
sed
contoh untuk menghindari (:-)) dan lebih banyak komentar.Jika Anda ingin menghindari keajaiban dan drama pembatas melingkar dan file dummy, Anda bisa menambahkan pembatas Anda ke satu file sebelum menempelkannya:
memberi
sumber
Anda bisa melakukannya dengan python juga dengan cara ini.
sumber