私は多くのファイルをダウンロードしてコンパイルするプロジェクトを持っています。このファイルについて私ができる仮定は次のとおりです。
- 最上位ディレクトリは1つだけです。
- フォルダ名がtar.xz/gzファイル名と必ずしも一致する必要はありません。つまり、Something-1.3.5a.tar.gzをSomething-1.3.5というフォルダに抽出できます。
入力量を減らすために、以下を実行する小さなスクリプトを作成しました。
- tar.xz/gz ファイルの抽出
- cdでディレクトリに入ります
私の現在のハッキングは、次のことを行うことです。
test1=$(tar -axvf something-1.3.5a.tar.gz)
cd $(echo $test1 | cut -f1 -d" ")
基本的にこれが行うことは、抽出の出力をキャプチャし、最初の行(トップレベルディレクトリ)をインポートしてからそこにCDを挿入することです。
だから私の質問は、これを行うよりクリーンでより良い方法がありますか?
答え1
#!/bin/sh
Dir_name=`tar -tzf something-1.3.5a.tar.gz | head -1 | cut -f1 -d"/"`
echo $Dir_name
tar options details,
-t, --list
-z, --gzip, --ungzip filter the archive through gzip
-f, --force-local archive file is local even if has a colon
ここでは、tarのファイルのリストを取得し、head -1
cmdを使用して最初の行を取得し、cmdを切り取り、最初のフィールドを抽出します。
答え2
トップレベルのディレクトリがありますが、そこに何もない場合は、tarを実行する前にどのディレクトリがあるのかを覚えています。
# ksh terminology: set -A BEFORE .*/ */
BEFORE=(.*/ */)
tar -xf blah blah blah
AFTER=(.*/ */)
# We can make it O(n), since glob outputs can be assumed to be sorted.
# Do it.
for (( i = 0; i < "${#BEFORE[@]}"; i++ )); do
[ "${BEFORE[i]}" == "${AFTER[i]}" ] || break
done
cd "${AFTER[i]}"
for
これは、算術、0から始まる配列インデックスを使用し、${#arr[@]}
配列メンバー数にアクセスするすべてのシェルで機能します。
事実上マッチングがないところ*/
まで拡張が可能なため問題がある。 (タグのためにbashを使用すると仮定すると)これを設定できます*/
。bash
shopt -s nullglob
ワイルドカードをディレクトリに制限すると、*/
ファイルについて心配する必要はありません。追加ファイルはまだ1つのディレクトリにします。 :)
答え3
tar.bz2ファイルを使用すると、次のような結果は得られません。
0 0 2019-04-02 17:20 folder name
-tf オプションを使用しています。
tar -tf file_name.tar.bz2 | head -1 | cut -f1 -d"/"