Hapus semua baris yang dimulai dengan # dari file

182

Semua baris dengan komentar dalam file dimulai dengan #. Bagaimana saya bisa menghapus semua baris (dan hanya baris itu) yang dimulai dengan #? Baris lain yang berisi #, tetapi tidak di awal baris harus diabaikan.

Desa
sumber
1
Apakah itu harus bekerja dengan konvensi umum yang #blah \<nl>blahdianggap sebagai satu "garis logis" karena garis miring terbalik dari baris baru?
sarnold
@sarnold: selain make, utilitas mana yang menggunakan 'garis backslash splices sebelum mengakhiri komentar'? Kerang (bash dan ksh diuji) tidak. C dan C ++ menangani splicing baris baru sebelum pemrosesan arahan preprosesor lainnya, tetapi arahan bukan komentar.
Jonathan Leffler
@ Jonathan: Luar biasa. Saya berasumsi bahwa \<nl>pelarian bersama juga akan berfungsi pada komentar. Tapi wow saya salah. Saya belum dapat menemukan contoh lain ... :) Terima kasih!
sarnold

Jawaban:

302

Ini dapat dilakukan dengan sed one-liner :

sed '/^#/d'

Ini mengatakan, "temukan semua baris yang dimulai dengan # dan hapuslah, tinggalkan yang lainnya."

Raymond Hettinger
sumber
9
versi lebih pendek:sed /^#/d
kev
80
Untuk noobs linux seperti saya:sed '/^#/ d' < inputFile.txt > outputFile.txt
Neil McGuigan
50
Versi Terpendek: sed -i '/^#/d' filepath.
lesderid
14
Dan sed -i '' '/^#/d' filepathdi Mac ( karena sufiks -i adalah wajib )
paulcm
1
@ Viesturs Coba ini: awk '/^#/ && !first { first=1 ; next } { print $0}'
Raymond Hettinger
56

Saya sedikit terkejut tidak ada yang menyarankan solusi yang paling jelas:

grep -v '^#' filename

Ini menyelesaikan masalah seperti yang dinyatakan.

Tetapi perhatikan bahwa konvensi umum adalah untuk segala sesuatu dari a #hingga akhir baris untuk diperlakukan sebagai komentar:

sed 's/#.*$//' filename

meskipun itu memperlakukan, misalnya, #karakter dalam string literal sebagai awal komentar (yang mungkin atau mungkin tidak relevan untuk kasus Anda) (dan meninggalkan baris kosong).

Baris yang dimulai dengan spasi putih sewenang-wenang yang diikuti oleh #mungkin juga diperlakukan sebagai komentar:

grep -v '^ *#' filename

jika spasi putih hanya spasi, atau

grep -v '^[  ]#' filename

di mana kedua spasi sebenarnya adalah spasi diikuti oleh karakter tab literal (ketik "control-v tab").

Untuk semua perintah ini, abaikan filenameargumen untuk membaca dari input standar (misalnya, sebagai bagian dari pipa).

Keith Thompson
sumber
Saya telah menambahkan jawaban baru yang dibangun berdasarkan jawaban ini.
Acumenus
Saya punya masalah menggunakan grep dengan cara ini di Windows. Solusinya adalah mengganti 'dengan ", misalnyagrep -v "^#" filename
Serg
14

Kebalikan dari solusi Raymond:

sed -n '/^#/!p'

"jangan cetak apa pun, kecuali baris yang TIDAK mulai dengan #"

ata
sumber
9

Anda dapat langsung mengedit file Anda dengan

sed -i '/^#/ d'

Jika Anda ingin, hapus juga baris komentar yang dimulai dengan penggunaan spasi putih

sed -i '/^\s*#/ d'

Biasanya, Anda ingin mempertahankan baris pertama skrip Anda, jika itu adalah sha-bang, jadi sedsebaiknya jangan hapus baris yang dimulai dengan #!. juga harus menghapus baris, yang hanya berisi hash tetapi tidak ada teks. kumpulkan semuanya:

sed -i '/^\s*\(#[^!].*\|#$\)/d'

Agar sesuai dengan semua varian sed, Anda perlu menambahkan ekstensi cadangan ke -iopsi:

sed -i.bak '/^\s*#/ d' $file
rm -Rf $file.bak
rubo77
sumber
1
ditambah 1 untuk yang ruang
deepaksingh pawar
7

Anda dapat menggunakan yang berikut ini untuk solusi awk -

awk '/^#/ {sub(/#.*/,"");getline;}1' inputfile
jaypal singh
sumber
5

Jawaban ini dibangun berdasarkan jawaban sebelumnya oleh Keith .

egrep -v "^[[:blank:]]*#" harus menyaring baris komentar.

egrep -v "^[[:blank:]]*(#|$)" harus menyaring komentar dan baris kosong, seperti yang sering berguna.

Untuk informasi tentang [:blank:]dan kelas karakter lainnya, lihat https://en.wikipedia.org/wiki/Regular_expression#Character_classes .

Acumenus
sumber
Dengan asumsi Anda egrepmendukung sintaks itu; versi yang lebih lama mungkin tidak.
Keith Thompson
-3

Ini dia dengan loop untuk semua file dengan beberapa ekstensi:

ll -ltr *.filename_extension > list.lst

for i in $(cat list.lst | awk '{ print $8 }') # validate if it is the 8 column on ls 
do
    echo $i
    sed -i '/^#/d' $i
done
Bruno Damas
sumber