ls -1
は次のように私の要素をリストします:
foo.png
bar.png
foobar.png
...
次のように.png
なしでリストしたい:
foo
bar
foobar
...
(dirには.png
ファイルのみが含まれます)
この場合のgrep
の使い方を誰かに教えてもらえますか?
目的:すべての名前が拡張子なしでリストされているテキストファイルがあります。テキストファイルとフォルダーを比較して、不足しているファイルを確認するスクリプトを作成したいと考えています。
このジョブに必要なのはシェルだけです。
POSIXly:
for f in *.png; do
printf '%s\n' "${f%.png}"
done
zsh
の場合:
print -rl -- *.png(:r)
ls -1 | sed -e 's/\.png$//'
sed
コマンドは、ファイル名のendで見つかった文字列.png
を削除します(つまり、空の文字列で置き換えます)。
.
は\.
としてエスケープされるため、正規表現.
ではなく、sed
がリテラル.
文字として解釈されます(つまり、任意の文字に一致します) )。 $
は行末アンカーなので、ファイル名の途中の.png
とは一致しません。
Bashを使用したいだけの場合:
for i in *; do echo "${i%.png}"; done
一致を見つけようとするときはgrep
に手を伸ばす必要があります。その代わりにsed
を使用するのは適切ではありません。
find . -maxdepth 1 -name "*.png" | sed 's/\.png$//'
PNGファイルに順序を付けるためにいくつかのサブディレクトリを作成する必要があると判断したら、簡単に次のように変更できます。
find . -name "*.png" | sed 's/\.png$//'
私はbasename
に行きます(GNU実装を想定):
basename --suffix=.png -- *.png
別の非常によく似た答え(この特定のバリアントがまだ表示されていないことに驚いています)は次のとおりです。
ls | sed -n 's/\.png$//p'
ls
は、標準出力がターミナルではない場合(この場合はパイプ)を想定しているため、ls
に対する-1
オプションは必要ありません。sed
の-n
オプションは、「デフォルトでは行を印刷しない」ことを意味します/p
オプションは、「...置換が行われた場合にこの行を出力する」ことを意味します。その最終的な効果は、.png
を削除して、.png
で終わる行だけを出力することです。つまり、これはOPの質問のわずかな一般化にも対応しています。つまり、ディレクトリには.png
ファイルのみが含まれていません。
sed -n
手法は、通常はgrep + sedを使用する可能性がある場合に役立ちます。
これを行うには、BASHコマンドのみを使用できます(外部ツールなしで)。
for file in *; do echo "${file%.*}"; done
これは、/ usr/binがない場合に便利で、this.is.image.pngのようなファイル名とすべての拡張子に対して機能します。
ls
を解析したり、find
をパイプしたりするのは安全ではありません[ 1 、 2 ]ls
またはfind
の出力を解析(およびパイプ)するのは安全ではありません。主にファイル名で見つけることができるためです改行、タブなどの通常ではない文字...ここでは、純粋なシェルサイクルが機能します[ cuonglm ]。find
コマンドパイプなしオプション-exec
でも機能します。
find ./*.png -exec basename {} .png \;
pdates/Notes:find .
を使用して非表示のファイルを検索することも、find ./*.png
を使用して非表示でないファイルのみを取得することもできます。 find *.png -exec ...
を使用すると、.png
という名前のファイルが存在する場合に問題が発生する可能性があります。これは、findがオプションとして取得するためです。 -maxdepth 0
を追加すると、Dir_01.png
という名前のディレクトリへの下降を回避できます。また、maxdepthが許可されていない場合はfind ./*.png -Prune -exec ...
を追加できます(Stéphaneに感謝)。これらのディレクトリのリストを表示したくない場合は、オプション-type f
を追加する必要があります(これにより、他のタイプの非通常ファイルも除外されます)。 man
を調べて、利用可能なすべてのオプションの完全なパノラマを確認し、移植性を高めるために、それらがPOSIX準拠であるかどうかを確認してください。
たとえば、ドキュメントからタイトルをコピーしてファイル名に貼り付けると、1つ以上の改行がファイル名自体で終了することがあります。タイトルが改行の直前に使用する必要のあるキーすら含まれている可能性があるので、あまりにも不運な場合があります。
The new art of working on .png
files and other formats.
テストしたい場合は、次のコマンドでこのようなファイル名を作成できます
touch "A file with two lines"$'\n'"and This is the second.png"
touch "The new art of working on .png"$'\n'"files and other formats.png"
単純な/bin/ls *png
は、印刷できない文字の代わりに?
を出力します
A file with two lines?and This is the second.png
The new art of working on .png?files and other formats.png
出力をパイプするls
またはfind
のすべてのケースで、現在の行が新しいファイル名、または前のファイル名で改行文字の後に続く場合nastyの名前は確かにありますが、それでも正当な名前です。
Shell Parameter-Expansion、${parameter%Word}
、printf
またはecho
の両方のバリアントでのシェルサイクルは機能します [ cuonglm ]、[ Anthon1 ] 。
for f in *.png; do printf "%s\n" "${f%.png}" ; done
Shell Parameter Expansionのmanページから []
$ {parameter%Word}
$ {parameter %% Word}...展開の結果は、最短一致パターン( ‘%’ケース)または最長一致パターン( ‘%%’ケース)が削除されたパラメーターの値です。
それで十分でしたか?
ls -1 | sed 's/\.png//g'
または一般的に、これ
ls -1 | sed 's/\.[a-z]*//g'
すべての拡張機能を削除します
rev
を使用:
ls -1 | rev | cut -f 2- -d "." | rev
rev
はすべての文字列(行)を逆にします。最初の '。'の後にすべてをカットします。 revは残りを逆転させます。
grep
'alma'にしたい場合:
ls -1 | rev | cut -f 2- -d "." | rev | grep 'alma'
ディレクトリに拡張子が.pngのファイルしかないことがわかっている場合は、次のコマンドを実行するだけです:ls | awk -F. '{print $1}'
これは、filename.extensionがあるすべての場所の最初の「フィールド」を返します。
例:
[rsingh@rule51 TESTDIR]$ ls
10.png 1.png 2.png 3.png 4.png 5.png 6.png 7.png 8.png 9.png
[rsingh@rule51 TESTDIR]$ ls | awk -F. '{print $1}'
10
1
2
3
4
5
6
7
8
9
あなたのコメントによると「拡張子のないすべての名前がリストされているテキストファイルがあります。PHPスクリプトを作成して、テキストファイルとフォルダーを比較して、どのファイルが"がありません:
for file in $(cat yourlist) ; do
[ -f "${file}.png" ] || {
echo "$file : listed in yourlist, but missing in the directory"
}
done
#assumes that filenames have no space...
# otherwise use instead:
# while IFS= read file ; do ...(same inner loop as above)... ; done < yourlist
そしてその逆:
for file in *.png ; do
grep "^${file%.png}$" yourlist >/dev/null || {
echo "$file: present in the directory but not listed in yourlist"
}
done
#I assume there are no spaces/tabs/? before/after names in 'yourlist'. Change the script accordingly if there are some (or sanitize the list)
スーパーレーターが「。」であるlsの出力について、次のフィードを試すことができます。すべてのファイルにname.pngが含まれるため、最初の列を印刷します。ls | awk -F"." '{print $1}'
単純なシェル行(ksh、bashまたはzsh、ダッシュではない):
set -- *.png; printf '%s\n' "${@%.png}"
単純な関数(拡張なしから):
ne(){ set -- *.png; printf '%s\n' "${@%.png}"; }
または、指定された拡張子を削除する関数(デフォルトではPNG):
ne(){ ext=${1:-png}; set -- *."$ext"; printf '%s\n' "${@%.${ext}}"; }
使用:
ne jpg
出力がアスタリスクの場合*
、その拡張子を持つファイルは存在しません。
ls -l | sed 's/\.png$//'
@roaimaで強調表示されている最も正確な方法です。エスケープされた\.png
がないと、a_png.png
という名前のファイルはa_
としてリストされます。