時には、次のls出力形式のファイルを取得します。
/etc/cron.d:
-rw-r--r-- 1 root root 128 May 15 2020 0hourly
-rw------- 1 root root 235 Dec 17 2020 sysstat
/etc/cron.daily:
-rw------- 1 root root 235 Dec 17 2020 sysstat
一般的なGnuツールを使用するか、bashの内部を削除してそれを操作する機会がありますか?
-rw-r--r-- 1 root root 128 May 15 2020 /etc/cron.d/0hourly
-rw------- 1 root root 235 Dec 17 2020 /etc/cron.d/sysstat
-rw------- 1 root root 235 Dec 17 2020 /etc/cron.daily/sysstat
素晴らしいです。
最も簡単な方法は、次のようにファイルパスを削除することです。
cat <filename> | grep -v -E "^\/[a-z]"
しかし、私が言ったように、このパスをファイル名の後続行にどのように移動できますか?
与えられたコマンドは次のとおりですls -lR /etc/cron* > <filename>
。
私はその出力には影響しませんが、lsによって実行されたこれらのコマンドの出力を<filename>
私に送信される別のファイルにリダイレクトします。
私がやりたいことは、その内容を言及された2番目の結果に操作することです。デフォルトでは、最初の行をインポートしてファイルの2行目と3行目にパスを適用し、4行目をインポートして5行目に適用します。その後、これを一般的な方法で設定します。
awkを使うと効果があると思います。
答え1
ファイル名またはディレクトリ名にスペースが含まれていない場合は、POSIX awkを使用して次のことを実行できます。
$ awk '
NF==1 && sub(/:$/,"/") { dir=$0; next }
match($0,/[^[:space:]]+$/) { $0=substr($0,1,RSTART-1) dir substr($0,RSTART) }
{ print }
' file
-rw-r--r-- 1 root root 128 May 15 2020 /etc/cron.d/0hourly
-rw------- 1 root root 235 Dec 17 2020 /etc/cron.d/sysstat
-rw------- 1 root root 235 Dec 17 2020 /etc/cron.daily/sysstat
または、ファイル/ディレクトリ名にスペースを含めることができますが、ディレクトリパスが常に次から始まり、出力に/
常にls
ファイル名の前にまったく同じ数のフィールドがある場合(例のように)、次のことができます。
$ awk '
/^\// && sub(/:$/,"/") { dir=$0; next }
match($0,/^([^[:space:]]+[[:space:]]+){8}/) { $0=substr($0,1,RLENGTH) dir substr($0,RLENGTH+1) }
{ print }
' file
ただしls
、これらのフィールドを使用して出力を生成することは必ずしも可能ではありません(ls
日付/時刻出力はファイルの寿命とロケールによって異なり、たとえばユーザーIDにスペースを含めることができます)、各ファイル行のすべての文字が表示されることがありますあります。ファイル名とディレクトリ名には:
YMMVを除く任意の文字を含めることができるため、ディレクトリ名はユーザーが思う/
ように終了できます。NUL
行を区別し、各ファイル行でファイル名を見つけます。さらに、ファイル名に改行文字を含めることができます。これはまったく別の問題です。
ls
したがって、生成できるすべての可能な出力を解析する信頼できる方法はありません。これを行うには、呼び出すコンテキストに関係なく十分だと思うか、必要なパターンマッチングが何であるかを把握し、それに基づいてスクリプトをls
作成します。
一部の他のツールはls
解析する必要がある出力ファイルを生成するため、解析を試みるべきではないことを私たち全員が知っているので、他のツールを修正する必要がありますls
(参照http://mywiki.wooledge.org/ParsingLsそしてなぜ`ls`を解析しないのですか*(そしてどうすればいいですか?))したがって、このツールは失敗します。
答え2
使用しているコマンドまたはこの出力が表示される理由を示していないが、目標が一致するすべてのファイルとディレクトリを一覧表示する場合は、/etc/cron*
代わりに次のように使用できますfind
。
find /etc/cron*
または完全なリストが必要な場合(GNU find
):
find /etc/cron* -ls
どのfind
:
find /etc/cron* -exec ls -ld {} +
私のArch Linuxの出力例は次のとおりです。
$ ls /etc/cron*
/etc/cron.deny /etc/crontab /etc/crontab~ /etc/crontab.pacnew
/etc/cron.d:
0hourly
/etc/cron.daily:
/etc/cron.hourly:
0anacron
/etc/cron.monthly:
/etc/cron.weekly:
そしてfind
:
$ find /etc/cron* -ls
262172 4 drwxr-xr-x 2 root root 4096 Jan 23 19:41 /etc/cron.d
263666 4 -rw-r--r-- 1 root root 128 Jan 14 14:59 /etc/cron.d/0hourly
262173 4 drwxr-xr-x 2 root root 4096 Sep 30 11:38 /etc/cron.daily
262618 4 -rw-r--r-- 1 root root 74 Jan 14 14:59 /etc/cron.deny
262174 4 drwxr-xr-x 2 root root 4096 Jan 23 19:41 /etc/cron.hourly
263665 4 -rwxr-xr-x 1 root root 843 Jan 14 14:59 /etc/cron.hourly/0anacron
262175 4 drwxr-xr-x 2 root root 4096 Jun 30 2016 /etc/cron.monthly
262632 0 -rw-r--r-- 1 root root 0 Oct 31 2017 /etc/crontab
262633 4 -rw-r--r-- 1 root root 49 Sep 22 2017 /etc/crontab~
272465 4 -rw-r--r-- 1 root root 119 Jan 14 14:59 /etc/crontab.pacnew
262176 4 drwxr-xr-x 2 root root 4096 Sep 30 11:38 /etc/cron.weekly
275802 4 -rwxr--r-- 1 root root 68 Sep 30 11:37 /etc/cron.weekly/clamscan.sh
答え3
ソリューションTXR不明瞭な音声。
ls
この出力をどこかから取得し、それを使用する必要があるという事実を当然に考えてください。元の時間と機械に戻って他の形式で情報を取得することはできません。
$ txr lsdata.tl < lsdata
-rw-r--r-- 1 root root 128 May 15 2020 /etc/cron.d/0hourly
-rw------- 1 root root 235 Dec 17 2020 /etc/cron.d/sysstat
-rw------- 1 root root 235 Dec 17 2020 /etc/cron.daily/sysstat
どこlsdata.tl
:
(let ((curdir ""))
(whilet ((line (get-line)))
(match-case line
(`@dir:` (set curdir dir))
(`@{metadata 39} @name` (put-line `@metadata @curdir/@name`)))))
完璧ではありません。で終わる名前でだまされます:
。ディレクトリ行領域が常に絶対パスであると仮定できる場合は、それを一致に含めることができます。
(let ((curdir ""))
(whilet ((line (get-line)))
(match-case line
(`/@dir:` (set curdir dir))
(`@{metadata 39} @name` (put-line `@metadata /@curdir/@name`)))))
答え4
何が欲しいのかわかりませんが、次のコマンドを試してください。
$ ls -la | awk -v path=$PWD '{$NF=path"\/"$NF;print}' |sed 's| /| \t/|g'
ルートの並べ替えに興味がない場合は、sed部分を削除できます。