Katakanlah bahwa selama hari kerja Anda, Anda berulang kali menemukan bentuk output yang dikolomisasi dari beberapa perintah berikut di bash (dalam kasus saya dari mengeksekusi svn st
di direktori kerja Rails saya):
? changes.patch
M app/models/superman.rb
A app/models/superwoman.rb
untuk bekerja dengan output dari perintah Anda - dalam hal ini nama file - semacam penguraian diperlukan sehingga kolom kedua dapat digunakan sebagai input untuk perintah berikutnya.
Apa yang saya lakukan adalah menggunakan awk
untuk mendapatkan di kolom kedua, misalnya ketika saya ingin menghapus semua file (bukan itu usecase khas :), saya akan melakukan:
svn st | awk '{print $2}' | xargs rm
Karena saya sering mengetik ini, pertanyaan alami adalah: apakah ada cara yang lebih pendek (dengan demikian lebih dingin) untuk mencapai ini di bash?
CATATAN: Apa yang saya tanyakan pada dasarnya adalah pertanyaan perintah shell meskipun contoh konkret saya ada di alur kerja svn saya. Jika Anda merasa alur kerja itu konyol dan menyarankan pendekatan alternatif, saya mungkin tidak akan memilih Anda, tetapi yang lain mungkin, karena pertanyaan di sini adalah benar-benar bagaimana cara mendapatkan output perintah kolom ke-n di bash, dengan cara sesingkat mungkin . Terima kasih :)
Jawaban:
Anda dapat menggunakan
cut
untuk mengakses bidang kedua:Sunting: Maaf, tidak menyadari bahwa SVN tidak menggunakan tab dalam outputnya, jadi itu agak tidak berguna. Anda dapat menyesuaikan
cut
dengan output tetapi agak rapuh - sesuatu seperticut -c 10-
akan berfungsi, tetapi nilai pastinya akan tergantung pada pengaturan Anda.Pilihan lain adalah sesuatu seperti:
sed 's/.\s\+//'
sumber
cut -f2
dengansvn st
output. Anda akan melihatnya tidak berfungsi.svn st
akan menggunakan tab dalam outputnya. Setelah beberapa pengujian, sepertinya ini bukan masalahnya. Sial.-d
memungkinkan ini bekerja.cut -d" " -f2
.Untuk mencapai hal yang sama seperti:
hanya menggunakan bash yang dapat Anda gunakan:
Memang, ini tidak lebih pendek, tetapi sedikit lebih efisien dan menangani spasi putih di nama file Anda dengan benar.
sumber
a
danb
, bagaimana mendapatkannya?a
mewakili kolom pertama danb
mewakili kolom lainnya. Jika Anda ingin mencetak kolom kedua, gunakanread a b c;
lalu gunakanecho
sebagai gantirm
. Saya menggunakan ini untuk mendapatkan banyak proses ID yang mengikuti pola grep, jadi saya bisa menginterupsi semuanya.Saya menemukan diri saya dalam situasi yang sama dan akhirnya menambahkan alias ini ke
.profile
file saya :Yang memungkinkan saya untuk menulis hal-hal seperti ini:
sumber
function c() { awk "{print \$$1}" }
Maka Anda dapat melakukan:svn st | c 2 | xargs rm
Coba zsh. Ini mendukung alias suffix, jadi Anda dapat mendefinisikan X di .zshrc menjadi
maka kamu bisa melakukan:
Anda bisa melangkah lebih jauh dan mendefinisikannya untuk kolom ke-n:
yang akan menampilkan kolom ke-n dari file "file". Anda dapat melakukan ini untuk keluaran grep atau keluaran lebih sedikit juga. Ini sangat berguna dan fitur pembunuh dari zsh.
Anda dapat melangkah lebih jauh dan mendefinisikan D menjadi:
Sekarang Anda dapat mengetik:
untuk menghapus semua file yang disebutkan di kolom pertama file "file".
Jika Anda tahu bash, zsh tidak banyak berubah kecuali untuk beberapa fitur baru.
HTH Chris
sumber
cut
opsi ini. Itu tidak bekerja pada mesin saya menggunakan output darisvn st
. Cobasvn st | cut -d' ' -f2
lihat apa yang terjadi.Karena Anda sepertinya tidak terbiasa dengan skrip, berikut ini contohnya.
Jika Anda menyimpan ini
~/bin/x
dan pastikan~/bin
ada di AndaPATH
(sekarang adalah sesuatu yang Anda bisa dan harus dimasukkan ke dalam Anda.bashrc
), Anda memiliki perintah sesingkat mungkin untuk umumnya mengekstraksi kolom n; x n.Script harus melakukan pengecekan kesalahan dan jaminan yang tepat jika dipanggil dengan argumen non-numerik atau jumlah argumen yang salah, dll; tetapi memperluas pada versi esensial tanpa tulang ini akan ada di unit 102.
Mungkin Anda ingin memperluas skrip untuk memungkinkan pembatas kolom yang berbeda. Awk secara default mem-parsing input ke bidang di whitespace; menggunakan pembatas yang berbeda, menggunakan
-F ':'
mana:
adalah pembatas baru. Menerapkan ini sebagai opsi untuk skrip membuatnya sedikit lebih lama, jadi saya meninggalkan itu sebagai latihan untuk pembaca.Pemakaian
Diberikan file
file
:Anda bisa meneruskannya melalui stdin (menggunakan yang tidak berguna
cat
hanya sebagai pengganti untuk sesuatu yang lebih berguna);Atau berikan sebagai argumen untuk skrip:
Di sini,
sh script.sh
diasumsikan bahwa skrip disimpan sepertiscript.sh
dalam direktori saat ini; jika Anda menyimpannya dengan nama yang lebih berguna di suatu tempat di AndaPATH
dan tandai itu dapat dieksekusi, seperti dalam instruksi di atas, jelas gunakan nama yang berguna sebagai gantinya (dan tidak adash
).sumber
awk -v col=$col ...
cat
contoh untuk alasan histeris (-:Sepertinya Anda sudah punya solusi. Untuk mempermudah, mengapa tidak hanya menempatkan perintah Anda dalam skrip bash (dengan nama pendek) dan jalankan saja alih-alih mengetikkan perintah 'panjang' itu setiap waktu?
sumber
.bashrc
? Mengapa Anda mengacaukannya dengan hal-hal yang tidak terkait dengan bash. Apa yang saya lakukan adalah saya menulis skrip individual untuk setiap 'set' perintah dan menempatkan semuanya dalam~/scripts
direktori. Kemudian tambahkan seluruh~/scripts
ke sayaPATH
sehingga saya bisa memanggil mereka dengan nama saat saya membutuhkannya.Jika Anda ok dengan memilih kolom secara manual, Anda bisa sangat cepat menggunakan pick :
Pergi saja ke sel mana saja dari kolom ke-2, tekan
c
lalu tekanenter
sumber
Catatan, path file itu tidak harus di kolom kedua dari output svn st. Misalnya jika Anda memodifikasi file, dan memodifikasi propertinya, itu akan menjadi kolom ke-3.
Lihat contoh output yang mungkin di:
Contoh output:
Saya sarankan untuk memotong 8 karakter pertama dengan:
Jika Anda ingin 100% yakin, dan berurusan dengan nama file mewah dengan spasi putih di akhir misalnya, Anda perlu mengurai output xml:
Tentu saja Anda mungkin ingin menggunakan parser XML nyata, bukan grep / sed.
sumber