' ls -1 ':拡張子なしでファイル名を一覧表示する方法

ls -1は私の要素を次のようにリストします:

foo.png bar.png foobar.png ... 

のように:

foo bar foobar ... 

(dirには.pngファイルのみが含まれます)

この場合のgrepの使用方法を教えてもらえますか?

目的:すべての名前がリストされているテキストファイルがあります。拡張。テキストファイルとフォルダを比較して、どのファイルが欠落しているかを確認するスクリプトを作成したいと思います。

コメント

  • 注意が必要です。このようなリクエスト。 Linuxにはファイル名拡張子がありません。 Linuxには、.が含まれる場合と含まれない場合があるファイル名があります。規則では、最後に.pngを付けてファイルに名前を付けるように定められていますが、’という名前のpngファイルを作成できない理由はありません。 foo.zipまたはmy.picture.20160518または単にmypic
  • @hymie I知っていますが、そのフォルダ内の私の要素はすべて、末尾に.pngが付いた名前が付けられています。
  • ‘ ” extension “? ‘はUnixファイルの命名の一部ではありません。 ‘はVMS / NT / Windowsからのキャリーオーバーです。そして、あなたの若者も私の芝生から降ります。 🙂
  • ‘がこれを誇張しないようにしましょう。 OSは拡張子を単にファイル名の一部として扱いますが、コンパイラからGUIまで、多くのUNIXプログラムが拡張子に注意を払っています。この概念は、UNIXにとって異質ではないことは間違いありません。
  • 通常、 ls と、lsfindの出力をパイプ処理します。これは主に、`ファイル名のタブ文字。ファイル名がThe new art of working on .png\NEWLINE files and other formatsの場合、提案された解決策の多くで問題が発生します。

回答

このジョブに必要なのはシェルのみです。

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の出力をパイプ処理して解析することは避けたほうがよいでしょう。多くの場合、よく隠された驚きが残されています…(一部の単語
  • おそらく、最後の例ではfindechoのようなものに置き換えます。 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 -cls *.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のように、複数の.を含むファイル名、およびが良くないファイル名でも名前、内部に特殊文字が含まれています。改行として、またはawkRSの(入力)レコード区切り文字として使用する行として。 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$//'内ですが、これは今書いた答えになります。 🙁 note2 awkls | 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/\.[^.]*$//をお試しください。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です