web-dev-qa-db-ja.com

bashスクリプトにローカルファイルを$ 1にフィードして、ファイルの絶対パスをエコーさせることはできますか?

かなり自明です。

最初の引数は次のとおりです。

  • ファイルが存在するかどうかを確認しました
  • そのファイルの絶対パスをエコーする

例えば:

+akiva@akiva-ThinkPad-X230:~$ ./myscript myfile.txt
/home/akiva/myfile.txt

ありがとう

9
Akiva

スクリプトが

#!/bin/bash
[[ -e "$1" ]] && readlink -f -- "$1"

実行許可(chmod u+x scriptname)があります

./scriptname file

ファイルが存在する場合にフルパスを取得するには(ただし、 Sergが正しいreadlink -eGeorgeが正しい ではなくrealpathを使用するとテストは冗長になります) readlink

ノート

  • [[ -e "$1" ]]スクリプトの最初の引数である$1が存在するかどうかをテストします
  • &&成功した場合(前のコマンドが成功した場合)、次のコマンドを実行します
  • readlink -f -- "$1"はフルパスを出力します($1がシンボリックリンクであっても、実際のファイルへ)

OPは特殊文字をエスケープ付きで印刷するよう要求しました。スマートな方法*がなければなりませんが、私はこのようにしました(ただし、単一引用符は扱いませんが、それでもエスケープすることはできません)

[[ -e "$1" ]] && readlink -f -- "$1" | sed -r 's/\||\[|\]| |!|"|\$|%|\^|&|\*|\(|\)\{|\}|\#|@|\;|\?|<|>/\\&/g'

あなたが心配しているスペースだけであれば、それを作ることができます

sed 's/ /\\ /g'

これは、一重引用符(あまり有用ではありません)とスペースを取得します

sed -r "s/'| /\\\&/g"

しかし、一重引用符と二重引用符の両方をキャッチできるとは思わない...

*これが賢い方法です。 steeldriver に100%貢献

[[ -e "$1" ]] && printf "%q\n" "$(readlink -f -- "$1")"
7
Zanna

スクリプトは必要ありません。単一のreadlinkコマンドで十分です。

$ cd /etc/

$ readlink -e passwd
/etc/passwd

man readlinkから:

   -e, --canonicalize-existing
          canonicalize by following every symlink in every component
          of the given name recursively, all components must exist
8
#!/bin/bash

[[ -e "$1" ]] && echo realpath -e "$1"

英数字以外の文字を処理するための更新:

#!/bin/bash

[[ -e "$1" ]] && echo "$1" | sed -r 's/[^a-zA-Z0-9\-]/\//g' | realpath -e "$1"

スクリプトの準備:chmod +x script_name、次に

それを使用する:./script_name filename

情報:

  1. [[ -e "$1" ]]:渡されたファイルが存在するかどうかを確認します。
7
George Udosen