列の内容に基づいて新しいディレクトリ/フォルダを作成します。

列の内容に基づいて新しいディレクトリ/フォルダを作成します。

以下のデータを含むフォルダを作成する必要があります。

フォルダ名は列1に基づいて一意に指定する必要があります。各フォルダA、B、C、Dの内容は、2列の対応する値でなければなりません。

また、各フォルダのアイテムの総数が必要です。

例えば。 「B」というフォルダには、フォルダ「B」の最後の行の総数である「3」という一意の行番号で、「B、B1、B2」が必要です。

データは次のとおりです。

col1    col2
A       A
B       B
B       B1
B       B2
C       C1
C       C2
C       C3
D       D1
D       D2

答え1

「フォルダの内容」がどういう意味なのかよくわかりません。これはディレクトリですか、それとも一種のファイルですか?ディレクトリを簡単に作成できる場合:

< /tmp/input.txt xargs -n2 bash -c 'mkdir -p $0/$1'

これは/tmp/input.txt、入力ファイル(例では)から一度に2つの引数を単純なbashスクリプトに送信することを意味しますmkdir -p $0/$1。これは、最初のパラメータ()が一番上にあり、2番目のパラメータが最初のパラメータ()の下にあるディレクトリを繰り返しmkdir -p生成することを意味します。$0$1

ディレクトリの代わりにファイルを生成するには、次のように変更できます。

< /tmp/input.txt xargs -n2 bash -c 'mkdir -p $0;touch $0/$1'

echo次のコマンドを挿入して進行状況を確認できます。

< /tmp/input.txt xargs -n2 bash -c 'echo mkdir -p $0;echo touch $0/$1'
mkdir -p A
touch A/A
mkdir -p B
touch B/B
mkdir -p B
touch B/B1
mkdir -p B
touch B/B2
...

-pディレクトリがすでに存在する場合は、失敗しないように ""フラグがまだ必要です。mkdirmkdir

答え2

まず、条件に合ったテーブルを描きます。つまり、各行の最初の項目はファイル名で、残りの行は内容です。これはawkコマンドを使用して簡単に実行できます。

$ awk  '{a[$1]=a[$1]" "$2} END {for (i in a) print i, a[i]}' q763074 | awk '{print $0, NF-1}'
A  A 1
B  B B1 B2 3
C  C1 C2 C3 3
D  D1 D2 2

(q763074は入力例です)

これで、その出力をこのループにパイプすることで完了します。

while read -r line; do
    #first item is the file name
    filename=$(echo $line | awk '{print $1}')

    #the rest is file contents
    content=$(echo $line | cut -d ' ' -f 2-)

    # create file and and write each item to a new line
    echo "$content" | tr ' ' '\n' > "$filename.txt"
done

答え3

これがzshを含む単純なtsvファイルであるとします。

#! /bin/zsh -
table=/path/to/your/file.tsv

typeset -A seen failed entries
ret=0
warn() {
  print -rC1 -u2 -- "$@"
  ret=1
}

{
  read -r header_ignored
  while IFS=$'\t\t' read -r dir file rest_ignored; do
    # sanity checks
    if [[ $dir = /* ]]; then
      warn "skipping $dir absolute path"
    elif [[ -z $dir ]]; then
      warn "skipping empty dir"
    elif [[ /$dir/ = */../* ]]; then
      warn "skipping $dir with .. path components"
    elif [[ /$file/ = */../* ]]; then
      warn "skipping $file with .. path components"
    else
      file=${dir%/}/$file
      if
        [[ $file:h != . ]] &&
          (( ! seen[\$file:h]++ )) &&
          ! mkdir -p -- $file:h
      then
        (( fail[\$file:h]++ ))
        warn
        continue
      fi
      if (( ! fail[\$file:h] )); then
        if true >> $file; then
          (( entries[\$dir]++ ))
        else
          warn
        fi
    fi
  done
  for k v in "${(@kv)entries}"; do
    print -r -- $v entries were successfully created in $k
  done

  exit $ret
} < "$table"

(テストされていません)

次の点に注意してください。

col1    col2
some/dir    subdir/file
./some/dir  subdir/file
some    dir/subdir/file
some/dir/subdir file
.   some/dir/subdir/file

たとえば、毎回同じファイルが「作成」されることを検出しません。

関連情報