I have to use a makefile in order to copy all the contents of say Folder 1 into Folder 2. The contents of folder 1 are 5 files having names as abc_1.c,abc_2.c,.. and so on.
The paths of folders 1 & 2 are both given as variables in makefile and then the command for copy is being given.
The problem is that even after using Wildcard function I am able to copy the entire folder 1 into folder 2, and not the contents of folder1.
Kindly help me out by suggesting a method to copy the contents of folder 1 into 2 and not the entire folder.
Following is the code snippet which I used initially :
PATH_1 = /ace/1/*
PATH_2 = /ace/2/
The code to copy : shell cp -rf ("$(PATH_1)") ("$(PATH_2)")
Pls dont mind the above line of code.
The main problem was in PATH_1 as the '*' was not resolved properly and the contents were not copied. On removing the '*' from PATH_1 the code worked but again it copied entire folder 1 into folder 2.
Later, I modified Path_1 as follows :
PATH_1 = /ace/1/(wildcard abc_*.c)
Still the same thing, the entire folder 1 is being copied into folder 2.
Kindly help me out with this.
Try something on these lines:
PATH1=/ace/1
PATH2=/ace/2
C_SRCS=$(wildcard $(PATH1)/abc_*.c)
copy:
cp -vi ${C_SRCS} $(PATH2)
The copy options v is for verbose & i is for interactive, which you can ignore if you want to.
This rule will fail with error with C_SRCS is empty, to prevent that you can have a slightly robust rule something on these lines:
copy:
for C_SRC in ${C_SRCS}; do \
cp -vi $$C_SRC $(PATH2); \
done
Hope this helps!
Related
I am trying to copy files over from an old file structure where data are stored in folders with improper names to a new (better) structure, but as there are 671 participants I need to copy, I want to use regex in order to streamline it (each participant has files saved in the same format). However, I keep getting a cp: cannot stat error message saying that no file/directory exists. I had assumed this meant that I had missed a / or put "" in the wrong location but I cannot see anything in the code that would suggest it.
My code is as follows (which I add a lot of comments so other collaborators can understand):
#!/bin/bash
# This code below copies the initial .nii file.
# These data are copied into my Trial Participant folders.
# Create a variable called parent_folder1 that describes initial mask directory e.g. folders for each participant which contains the files.
parent_folder1="/this/path/here/contains/Trial_Participants"
# The original folders are named according to ClinicalID_scandate_randomdigits e.g. folder 1234567890_20000101_987654.
# The destination folders are named according to TrialIDNumber e.g. LBC100001.
# The .nii files are saved under TrialIDNumber_1_ICV.nii.gz e.g. LBC1000001_1_ICV.nii.gz.
# These files need copied over from their directories into the Trial Participant folders, using the for loop function.
# The * symbol is used as a wildcard.
for i in $(ls -1d "${parent_folder1}"/*_20*); do
lbc=$(ls ${i}/finalMasks/*ICV* | sed 's/^.*\///'); lbc=${lbc:0:9}
cp "${parent_folder1}/${i}"/finalMasks/*_1_ICV.nii.gz /this/path/is/the/destination/path/${lbc}/
done
# This code uses regular expression to find the initial ICV file.
# ls asks for a list, -1 makes each new folder on a new line, d is for directory.
# *_20* refers to the name of the folders. The * covers the ClinicalID, _20* refers to the scan date and random digits.
# I have no idea what the | sed 's/^.*\///' does, but I think it strips the path.
# lbc=${lbc:0:9} is used to keep the ID numbers.
# cp copies the files that are named under TrialIDNumber(replaced by *)_1_ICV.nii.gz to the destination under the respective folder.
So after a bit of fooling around, I changed the code a lot (took out sed as it confuses me), and came up with this that worked. Thanks to those who commented!
# Create a variable called parent_folder1 that describes initial mask directory.
parent_folder1="/original/path/here"
# Iterate over directories in parent_folder1
for i in $(ls -1d "${parent_folder1}"/*_20*); do
# Extract the base name of the file in the finalMasks directory
lbc=$(basename $(ls "${i}"/finalMasks/*ICV*))
# Extract the LBC number from the file name
lbc=${lbc:0:9}
# Copy the file to the specific folder
cp "${i}"/finalMasks/${lbc}_1_ICV.nii.gz /destination/path/here/${lbc}/
done
I have no background of shell script. I would like to perform the concatenation of files in all subdirectories recursively, which I was able to achieve by the help of previous posts on stack overflow. But I am unable to name the concatenated file on the name of files which are getting concatenated e.g.
Subdirectories:
Sample_001
Sample_002
Sample_003
Sample_004
Files in sub directory: Sample_001:
Sample_001-123_R1_001.fastq.gz
Sample_001-123_R1_002.fastq.gz
I used command :
For d in ./*/; do( cd "$d" && cat R1 > d_R1.fastq); done
My question is how I can use 001 from my file name instead of d in "d_R1.fastq".
I was unable to understand how I can achieve this and where I should put another command in the loop I was using.
Thank you in advance for kind help.
Create 50 files whose names are from 1 to 50.
Create five folders (0, 10, 20, 30, 40).
Copy those 50 files into folders based on their name (for example, file 21 will go to folder 20).
I have created those files and folders, but have no idea how to move a specific file to specific folder. I tried writing
cp {1..9} /home/user/folder
but that's not acceptable. Is it possible to do using if and elif?
cp {1..9} /home/user/folder
That will work, except you should specify the right folder to copy to. Perhaps you meant one of these?
cp {1..9} /home/user/folder/0
cp {1..9} 0
Another way is to use wildcards. * matches any string and ? matches any one character. 2? will match the file names 20 through 29, for instance.
When you don't mind using a for loop instead of if and else you could use code like this:
#1
touch file{1..50}
#2
mkdir dir{0..40..10}
#3
for i in {1..4}; do
cp file${i}* dir${i}
done
cp file* dir0 # note that this will copy file50 into dir0
I working with linux, bash.
I have one directory with 100 folders in it, each one named different.
In each of these 100 folders, there is a file called first.bars (so I have 100 files named first.bars). Although all named first.bars, the files are actually slightly different.
I want to get all these files moved to one new folder and rename/number these files so that I know which file comes from which folder. So the first first.bars file must be renamed to 001.bars, the second to 002.bars.. etc.
I have tried the following:
ls -d * >> /home/directorywiththe100folders/list.txt
cat list.txt | while read line;
do cd $line;
mv first.bars /home/newfolder
This does not work because I can't have 100 files, named the same, in one folder. So I only need to know how to rename them. The renaming must be connected to the cat list.txt, because the first line is the folder containing the first file wich is moved and renamed. That file will be called 001.bars.
Try doing this :
$ rename 's/^.*?\./sprintf("%03d.", $c++)/e' *.bar
If you want more information about this command, see this recent response I gave earlier : How do I rename multiple files beginning with a Unix timestamp - imapsync issue
If the rename command is not available,
for d in /home/directorywiththe100folders/*/; do
newfile=$(printf "/home/newfolder/%d.bars" $(( c++ )) )
mv "$d/first.bars" "$newfile"
done
I have following architecture of files in a directory.
Directory
/A/abc.xyz
/B/abc.xyz
/C/abc.xyz
/D/abc.xyz
/E/abc.xyz
I want to execute a program on acb.xyz in each SubDirectory. Save Output files in different directory i.e. Directory/processed with the name of SubDirectory appended in the name of output files.
Can it be written in following way? Need corrections.
for i in `ls "Directory/"`
do
program.pl $i/abc.xyz > processed/$i-abc.xyz
done
for dir in Directory/*; do
program.pl "$dir/abc.xyz" > "processed/${dir##*/}-abc.xyz"
done
The ${dir##*/} part strips the leading directory names from $dir, so Directory/A becomes just A. I added quotes to ensure directory names with whitespace don't cause issue (a good habit, even if you know there are no spaces).
As an alternative to the string munging you could simplify this if you first change directory:
cd Directory
for dir in *; do
program.pl "$dir/abc.xyz" > "processed/$dir-abc.xyz"
done