ls -1
は私の要素を次のようにリストします:
foo.png bar.png foobar.png ...
のように:
foo bar foobar ...
(dirには.png
ファイルのみが含まれます)
この場合のgrep
の使用方法を教えてもらえますか?
目的:すべての名前がリストされているテキストファイルがあります。拡張。テキストファイルとフォルダを比較して、どのファイルが欠落しているかを確認するスクリプトを作成したいと思います。
コメント
回答
このジョブに必要なのはシェルのみです。
POSIXly:
for f in *.png; do printf "%s\n" "${f%.png}" done
:
print -rl -- *.png(:r)
コメント
- あり’
printf
は必要ありません。echo ${f%.png}
で十分です。 - @Conrad:echoを使用すると’ファイル名が正しく機能しない場合がありますが、ダッシュで開始するか、エスケープされたシーケンスを含めます。
- @DavidConrad: unix.stackexchange.com/a/65819/38906 も参照してください
- @DavidConradさらに、printfが組み込まれていると思います。エコーと同じように、’間違っている場合は誰かが私を修正します
回答
ls -1 | sed -e "s/\.png$//"
sed
コマンドは削除します(つまり、空の文字列に置き換えられます)の end にある任意の文字列.png
ファイル名。
.
は\.
としてエスケープされるため、は、正規表現.
ではなく、リテラルの.
文字として(つまり、任意のchに一致する) aracter)。 $
は行末アンカーであるため、ファイル名の途中の.png
と一致しません。
コメント
- OPは任意の拡張子を削除したいと思いますが、おそらく”最後の1つ”。したがって、他の点では適切な答えを次のように変更します。
sed 's/\.[^.]*$//'
- はい、その正規表現はその場合は機能します…ただし、OPがそれを希望する場合は、” .png ”
-
-1
は不要であり、ここではデフォルトです。 - @jlliagre
を指定する必要があります。’は、パイプがオンになっているときのデフォルトのみです。これは、一部の人にとっては隠れた驚きです。したがって、明示的にすると役立ちます。理解しています。これはスクリプトでも行うので、どのような種類のoかがわかります。 utput I ‘期待しています。
- 警告キー付きのファイル名の場合(
.png
)改行文字の前に、最後の文字だけでなく、その.png
も消去します。 lsの出力をパイプ処理して解析することは避けたほうがよいでしょう。多くの場合、よく隠された驚きが残されています…(回答にはいくつかの単語や参照があります)。
回答
bashを使用するだけの場合:
for i in *; do echo "${i%.png}"; done
sed
を削除/置換するためではなく、一致するものを見つけようとする場合はgrep
にアクセスする必要があります。より適切:
find . -maxdepth 1 -name "*.png" | sed "s/\.png$//"
PNGファイルに順序を付けるためにいくつかのサブディレクトリを作成する必要があると判断したら、それを次のように簡単に変更できます。
find . -name "*.png" | sed "s/\.png$//"
コメント
- ls -1 | sed ‘ s / .png // ‘はうまく機能します。ありがとうございます!
-
find
パイプからsed
のソリューションでは、次の場合に問題が発生する可能性があります。名前の一部として改行文字の直前にキー(.png
)が含まれるファイルが見つかります。find
またはls
の出力をパイプ処理して解析することは避けたほうがよいでしょう。多くの場合、よく隠された驚きが残されています…(一部の単語 - おそらく、最後の例では
find
をecho
のようなものに置き換えます。find
がそこで機能する目的が明確ではなく、結果はディレクトリ構造によって異なります(つまり、ディレクトリfiles.png
がある場合) - @BroSlowより賢明なものに更新されました。
回答
別の非常によく似た回答(これには驚いています特定のバリアントはまだ表示されていません)は次のとおりです。
ls | sed -n "s/\.png$//p"
-
-1
は必要ありませんls
のオプション。これは、ls
が、標準出力がターミナル(この場合はパイプ)でない場合に想定するためです。 -
-n
オプションのsed
は、「デフォルトで行を印刷しない」ことを意味します。 - 置換の最後にある
/p
オプションは、「…置換が行われた場合はこの行を出力する」ことを意味します。
ネットその効果は、.png
で終わる行のみをが削除されました。つまり、これは、ディレクトリに.png
ファイルのみが含まれていないというOPの質問のわずかな一般化にも対応しています。
sed -n
テクニックは、grep + sedを使用する可能性がある場合に役立つことがよくあります。
コメント
- ケアの方法が好きです以前は回答を書いていました。このソリューションでは、改行を含むファイル名に問題が発生し、名前の最初の部分が出力されません。さらに、キー(
.png
)改行文字の前:その場合、最後の部分だけを消去するのではなく、pngなしでその部分を印刷します。問題はあなたが考えていない場所に隠すことができるので…
- @Hastur You ‘正解です、原則として、 don ‘ t parse ls は、病理学的ファイル名を渡す際のさらなる問題(および解決策)をリストします。しかし、それを処理する最良の方法は、病的なファイル名を持たないようにする(doh!)です。また、’できない場合、またはそれらに対して堅牢である必要がある場合は、
find
または–おそらくより良い–sh
よりも強力な言語を使用してそれらを管理します(sh
ができるという事実すべてが’それが’それぞれの場合に最良の選択であることを意味するわけではありません)。シェルは最初に使いやすさを考慮して設計されています。 - 原則として使いやすさについては同意しますが、改行ごとにファイル名があると、このバリアントは失敗します。これは、たとえば、GUIでPDFから行をコピーして貼り付ける場合など、気付かれずに簡単に発生する可能性があるため、病理学的なファイル名は避けられると考えているだけです。
- さらにIMHO ‘は
ls
の解析を開始するのは簡単ですが、将来の問題が発生する可能性があります。スクリプトを作成することがよくあります。後で使用しますが、すでに制限を忘れてしまいます…(’人間、通常は’)。 提案find
の例(-exec
あり、パイプなし) (純粋なシェルであるため)より良いと思われる場合でも、 cuonglm ‘の1つに、堅実でposixに準拠して答えてください。 - これは、何らかの理由で
.png
divのストリップを削除したい場合に、’が行うこととほぼ同じです。 >ファイル名のリストからのサフィックス。’スクリプトに入れません。代わりに、’シェルプロンプトでコマンドを入力するだけです。そうすることで、私は’ m 仮定 “正気”ファイル名。 ‘ 1回限りの手動コマンドで実行することはたくさんありますが、’について自由に推測できます。現在のディレクトリでは、他のコンテキストで再利用される可能性のあるスクリプトではおそらく’実行しません。
回答
basename
を選択します(GNU実装を想定):
basename --suffix=.png -- *.png
コメント
- パイプで使用する場合は、GNUベース名を使用すると便利な場合があることに注意してください’ s
-z
(または--zero
)オプションで、(newline-separatedの代わりに)NUL-separatedを生成します)出力。
回答
これを行うには、BASHコマンドのみを使用できます(外部ツールなし)。
for file in *; do echo "${file%.*}"; done
これは、/ usr / binがなく、ファイル名に適している場合に便利ですl ikethis.is.image.pngおよびすべての拡張機能。
回答
十分ではありませんか?
ls -1 | sed "s/\.png//g"
または一般的に、これは
ls -1 | sed "s/\.[a-z]*//g"
すべての拡張機能を削除します
コメント
- そうでしたが、他のソリューションも機能します。
- すべてのUnix / Unix Likeシステムには、必須のユーティリティである
sed
がインストールされています(またはインストールされている必要があります)。標準による。 - 確かに、しかし
ls
は、出力が端末ではない場合、そのオプションなしでとにかくそれを行います。これはここに当てはまります。 - 警告
Image.png.jpg.png
のようなファイル名がある場合、ls -1 | sed 's/\.[a-z]*//g'
は失敗します。 (.png
)。Unixでは、 strange ファイル名をThe new art of working on .png?files and other formats.png
として許可されます。ここで、?
は新しい行の文字です。残念ながら、ls
の出力を単にパイプ/解析するすべてのソリューションで問題が発生します。そのような場合を管理するms … -
g
修飾子を使用する理由は何ですか?\.png
は、表示されるたびにではなく、行の最後でのみ削除する必要があります。
回答
ls
を解析したりfind
[
1 、 2 ]
安全ではありませんls
またはfind
の出力を解析(およびパイプ)します。これは主に、ファイル名で見つけることができるためです。 em> newline 、 tab などの通常とは異なる文字…ここでは、純粋なシェルサイクルが機能します [ cuonglm ] 。
find
コマンドでさえパイプされていませんオプション-exec
は機能します:
find ./*.png -exec basename {} .png \;
更新/メモ:find .
を使用して、非表示のファイルも検索できます。またはfind ./*.png
隠されていないものだけを取得します。 find *.png -exec ...
を使用すると、.png
という名前のファイルが存在する場合に問題が発生する可能性があります。これは、findがオプションとして取得するためです。 -maxdepth 0
を追加して、Dir_01.png
またはfind ./*.png -prune -exec ...
という名前のディレクトリに移動しないようにすることができます。 maxdepthは許可されていません(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
の出力をパイプ処理します。次のコマンドには理解するためのヒントがありません。現在の行が新しいファイル名からのものである場合、または前のファイル名の改行文字の後に続く場合。確かに厄介な名前ですが、それでも正当な名前です。
両方のシェルパラメータ拡張、${parameter%word}
を使用したシェルサイクルprintf
またはecho
のバリアントは [ cuonglm aで機能します>]、[ Anthon1 ] 。
for f in *.png; do printf "%s\n" "${f%.png}" ; done
マニュアルページからシェルパラメータ拡張の概要 [ 3 ]
$ {parameter%word}
$ {parameter %% word}…展開の結果は、一致するパターンが最も短いパラメーターの値( %の場合)または最長の一致パターン(「%%」の場合)が削除されました。
コメント
-
find
コマンドはビット変数です(たとえば、files.png
というディレクトリがある場合) - 親愛なる@BroSlow、上記の回答を書いたとき Iシェル呼び出しの引数として起動されたスクリプトで、コマンドラインによってその瞬間に存在する他の13個(すべて)のバリアントを試しました。同じことをして、期待どおりに動作するかどうか教えてください。
bash 4.3.11
、ダッシュ0.5.7-4、zsh(必要な場合)5.0.2でテストを行いました。さらに何かを追加するこの投稿をお気軽に読んでください。find
の出力の piping のメモについて同意します。このため、明示的に-exec
を提案しました。 、そして私はタイトルに書いた。:-)
。 - wikiをもう一度読み直してください。 ‘がここで説明している’であるため、例をパイプする必要があると思います。また、
ls
の最新バージョンの大部分では、出力がパイプまたはリダイレクトされても問題はありませんが、wikiに記載されているように、すべてのバージョンで機能するとは限りません。ほとんどの場合、出力が端末に送信されるときに、特殊文字の代わりに?
のみが挿入されます。つまり、echo *.png | od -c
とls *.png | od -c
を実行します。改行の問題はls
の問題ではなく、’が’ tヌルはパイプの両側で終端します。 -
printf "${f%.png}\n"
は間違っています。最初の引数はフォーマットです。’そこで変数データを使用しないでください。 DoSの脆弱性と見なされることもあります(たとえば、%1000000000s.png
ファイルを試してください)。 - あなた’ d
find ./*.png -prune -exec...
が必要であるか、’で-
で始まるファイル名(およびディレクトリを入力します。-maxdepth
は移植性がないことに注意してください)
回答
rev
を使用:
ls -1 | rev | cut -f 2- -d "." | rev
rev
はすべてを逆にします文字列(行);最初の「。」の後にすべてをカットします。そして、revは残りを元に戻します。
grep
“alma”を使用する場合:
ls -1 | rev | cut -f 2- -d "." | rev | grep "alma"
コメント
-
-1
は不要で、ここではデフォルトです。 - これ
My.2016.Summer.Vacation.png
- @DavidConradという名前のファイルでひどく失敗する私の悪い:/
cut -f 2-
liに修正しました> - 現在はそのファイルで機能しますが、
.png
と直後の改行を含むファイルではまだ機能しません… 驚きをうまく隠すのが大好きだから… 🙂
回答
ディレクトリに拡張子が.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
コメント
- 残念ながら、すべてで失敗します
Image.1.png
のように、複数の.
を含むファイル名、およびが良くないファイル名でも名前、内部に特殊文字が含まれています。改行として、またはawk
、RS
の(入力)レコード区切り文字として使用する行として。ls
の出力は、予期しないときに発生する問題を隠すのが大好きなので、解析しないことをお勧めします。詳細については、 1 または 2 を参照してください。ところで、awkを使用するというアイデアは素晴らしいです…私は1つの答えにいくつかの例を入れました。 - しかし、Colinによって提供されたサンプルを考えると、それは問題なく機能します。提案したケースで機能させるには、’次のように変更します。[rsingh @ rule51 TESTDIR] $ ls | sed -e ‘ s / .png $ // ‘ 10 1 2 3 4 5 6 7 8 9 harry.the.bunny whats .a.png.filename難しいことではありませんが、Colin ‘の必要性を考えると、’問題がどうなるかわかりませんlsを解析しています。
- 申し訳ありません… ‘ sedが’ ls ‘ [rsingh @ rule51 TESTDIR] $ ls 10.png 2.png 4.png 6.png 8.pngharry.the.bunny。 png 1.png 3.png 5.png 7.png 9.png whats.a.png.filename.png [rsingh @ rule51 TESTDIR] $ ls | sed -e ‘ s / .png $ // ‘ 10 1 2 3 4 5 6 7 8 9 harry.the.bunny whats .a.png.filename
- note1
\.
divの.
をエスケープする必要があります>sed -e 's/\.png$//'
内ですが、これは今書いた答えになります。 🙁 note2awk
をls | awk -F. '{if ($NF=="png") {for (i=1;i<NF-1;i++) printf("%s.", $i) ; printf $(NF-1)"\n"}}'
のようなもので使用してみることができます…しかし、常に、awkが行が到着しているかどうかを知ることができない問題は、ファイル名内の改行が続くかどうかです。私は答えでもっとよく言いたいと思いました。 - Hasturに感謝します、私はそれを逃しました:)。また、この場合はsedを優先してawkの使用をやめました。
回答
コメント「すべての名前が拡張子なしでリストされているテキストファイルがあります。テキストファイルとフォルダを比較して、どのファイルが欠落しているかを確認する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 -l | sed "s/\.png$//"
@roaimaで強調表示されているように、最も正確な方法です。エスケープされていない\.png
ファイルは、a_png.png
という名前で、a_
としてリストされます。
コメント
-
ls -l
を使用すると、ファイルの詳細が表示されますが、これはOPが要求したものではありません。約。
回答
単純なシェルライン(ダッシュではなく、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
出力がアスタリスク*
の場合、その拡張子を持つファイルは存在しません。
回答
次のフィードを試すことができます。スーパーレーターが「。」である場合の出力は次のとおりです。すべてのファイルにname.pngが含まれるため、最初の列を出力します。
ls | awk -F"." "{print $1}"
回答
sedにアクセスした場合は、(png、jpg、tiffなど)が何であれ、最後のファイル拡張子が削除されるため、これが適しています。
ls | sed -e "s/\..*$//"
コメント
-
this.is.a.dotty.txt
のようなファイル名の区切り。代わりにs/\.[^.]*$//
をお試しください。
.
が含まれる場合と含まれない場合があるファイル名があります。規則では、最後に.png
を付けてファイルに名前を付けるように定められていますが、’という名前のpngファイルを作成できない理由はありません。foo.zip
またはmy.picture.20160518
または単にmypic
。ls
と、ls
とfind
の出力をパイプ処理します。これは主に、`ファイル名のタブ文字。ファイル名がThe new art of working on .png\NEWLINE files and other formats
の場合、提案された解決策の多くで問題が発生します。