Переместите только те файлы, которые названы как указанные c строки в образце листа. - PullRequest
1 голос
/ 21 апреля 2020

Представьте, что у меня есть эти файлы в моем рабочем каталоге в bash:

123.tsv 456.tsv 789.tsv 101112.tsv 131415.tsv 

, и что у меня есть этот образец листа (разделенный табуляцией):

sampleID     tissue
123           lung
124           bone
456           lung
457           bone

Теперь я Я хочу переместить эти файлы, соответствующие образцам легких, в новый каталог, поэтому я хотел бы, чтобы в новом каталоге были следующие файлы:

123.tsv
456.tsv

Я пытался использовать:

awk -F"\t" '$2 == "lung"'

Но я не уверен, как включить это в a для l oop, чтобы выбрать имена файлов, включенные в первый столбец выходного файла, из команды awk. Как я могу решить это?

Ответы [ 3 ]

2 голосов
/ 21 апреля 2020

Если номер строки больше 1, а во втором столбце содержится lung, выведите содержимое первого столбца с текстом вокруг него:

mkdir new_dir
awk 'NR>1 && $2=="lung" {print "mv", $1 ".tsv new_dir"}' sample.sheet

Если вывод выглядит нормально, добавьте | sh к awk строка для выполнения команд.

1 голос
/ 21 апреля 2020
#!/bin/sh
#
#
me=$( basename "${0}" )

# Adjust these as needed. If you want to use your current
# working directory change (or remove) `/tmp/` to `./`.
old_dir="/tmp/foo"
new_dir="/tmp/bar"
list="/tmp/sample_sheet"

# Make sure all the pieces are available. Exit if not.
if [ ! -d "${old_dir}" ]
then
    echo "ERROR: ${me}: Source '${old_dir}' does not exist." 1>&2
    exit 1
elif [ ! -d "${new_dir}" ]
then
    echo "ERROR: ${me}: Target '${new_dir}' does not exist." 1>&2
    exit 2
elif [ ! -r "${list}" ]
then
    echo "ERROR: ${me}: Sample sheet input '${list}' does not exist." 1>&2
    exit 3
fi

# Iterate over the first column in `${list}`.
for file in $( awk 'NR>1 && $2=="lung" {print $1".tsv"}' "${list}" )
do
    # If the file exists move it, if not do nothing.
    if [ -f "${old_dir}/${file}" ]
    then
        echo "INFO: ${me}: mv ${old_dir}/${file} ${new_dir}/${file}"
        mv "${old_dir}/${file}" "${new_dir}/${file}"
    fi
done
0 голосов
/ 21 апреля 2020

Вот скрипт, который вы можете запустить, например, такой:

./move_files.sh lung

Это работает для обоих случаев (легкие и кости) и является общим. Поместите это в файл с именем move_files. sh:

#!/usr/bin/env bash

files=$(sed -e "s/\([0-9]\{3\}\)\( *$1\)/\1/g" <(grep $1 eg.sheet))
if [ ! -d $1 ]; then
  mkdir $1
fi
for t in ${files[@]}; do
  mv "./$t.tsv" $1
done

со следующим содержимым каталога:

101112.tsv  123.tsv  124.tsv  131415.tsv  456.tsv  457.tsv  789.tsv  eg.sheet  move_files.sh

и eg.sheet , содержащий:

sampleID     tissue
123           lung
124           bone
456           lung
457           bone

... запуск сценария с

./move_files.sh lung

... приводит к 123.tsv и 456.tsv перемещается во вновь созданный каталог lung (или просто перемещается туда, если каталог уже существует).

Затем можно просто запустить

./move_files.sh bone

для переместите 124.tsv и 457.tsv во вновь созданный каталог bone . Конечно, это тогда можно обобщить на все, что есть в например. Лист .


Примечание: вы должны запустить chomd +x move_files.sh, чтобы использовать его в так, как я предложил. В противном случае вы можете вызвать его с помощью bash move_files.sh lung.


РЕДАКТИРОВАТЬ:

Для решения вопроса, поднятого keithpjolley в комментариях, это все равно может работать с «тканями», такими как «eye la sh», просто заключая в кавычки переменную $1 и вызывая ее с помощью строки в кавычках (например, ./move_files.sh "eye lash"):

#!/usr/bin/env bash

files=$(sed -e "s/\([0-9]\{3\}\)\( *$1\)/\1/g" <(grep "$1" eg.sheet))
if [ ! -d "$1" ]; then
  mkdir "$1"
fi
for t in ${files[@]}; do
  mv "./$t.tsv" "$1"
done
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...