LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 01-15-2015, 03:07 PM   #1
00mpa
LQ Newbie
 
Registered: Feb 2013
Posts: 8

Rep: Reputation: Disabled
Trying to copy file output by read while command


The point of this is to look for certain types of files from a ton of directories and consolidate those files into one directory. What further complicates things is the fact that there are files with different version numbers and I can only copy over the latest one.

Below is how I tried to do that:

if [ -d ~/directory/*${tid}* ]; then
cd ~/directory/*${tid}*;
ls -rt file_L1b*.csv | tail -1

while read -r line; do
cp $line ~/test_dir/;
done
fi

The output that I get is :

usage: cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file target_file
cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file ... target_directory

Therefore, what do I need to change so that I can use the output of the read -r line which is a file name and copy it to the ~/test_dir/ directory. This was the only way that I could come up with so I'm not sure if there is an easier way to accomplish my goal.

Thanks!
 
Old 01-15-2015, 07:13 PM   #2
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,006

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
Ok ... a few things:

1. Please place data/code inside [code][/code] tags to make it more legible

2. Your use of wildcards is not going to workout so well, for example:
Code:
if [ -d ~/directory/*${tid}* ]; then
Now I will assume that 'tid' is being successfully set elsewhere in your code. This line says are there any directories below the path ~/directory that contain 'tid'.
This is quite different from saying is there a single directory in the path that exists and contains 'tid'

3. Just as there may be multiple directories tested, the cd may also get confused if there are multiple directories to change to

Now we get to the section causing your error:

4. The while loop has nothing feeding it so it would be waiting for user input on standard in (in your case the keyboard). Assuming you hit the enter key without typing anything, this would then fill the
'line' variable with nothing, hence your cp command would look like :- cp ~/test_dir/
As you can see this is an incomplete copy command and hence your error


The resolution is that you need to feed the file names to the while command. To have the output of a command sent to while it needs to be of the form:
Code:
while ...
do
  ...
done< <(your command here)
Please note there is a space between the 2 < symbols
 
Old 01-15-2015, 11:23 PM   #3
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,699

Rep: Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895
You do not need the while loop if you assign the output of the ls pipe command to a variable.

Code:
$latest_file=$( ls -rt file_L1b*.csv | tail -1 )
cp $latest_file ~/test_dir/
 
Old 01-16-2015, 06:40 AM   #4
mina86
Member
 
Registered: Aug 2008
Distribution: Debian
Posts: 517

Rep: Reputation: 229Reputation: 229Reputation: 229
Quote:
Originally Posted by grail View Post
2. Your use of wildcards is not going to workout so well, for example:
Code:
if [ -d ~/directory/*${tid}* ]; then
[…] This line says are there any directories below the path ~/directory that contain 'tid'.
Just to make it clear, this line is actually broken if there is more than one directory matching the wildcard. Observe:
Code:
$ mkdir /tmp/a && cd /tmp/a
$ mkdir foo1 foo2
$ tid=foo
$ test -d *${tid}*
-bash: test: foo1: binary operator expected
$ echo $?
2
Quote:
Originally Posted by grail View Post
The resolution is that you need to feed the file names to the while command. To have the output of a command sent to while it needs to be of the form:
Code:
while ...
do
  ...
done< <(your command here)
A more portable way is to do:
Code:
your command here | while …; do
    …
done
but beware of setting variables inside while loop and using it outside. And of course, if file names are read from a file it’s enough to do:
Code:
while …; do
    …
done <filename
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
How to Copy Terminal Output to a File SkM007 Linux - Newbie 10 01-03-2016 04:17 PM
Read mail server inbox and copy to text file using command line swathi.akkineni Linux - Newbie 1 10-11-2012 10:03 AM
[SOLVED] Bash script to read multiple variables from a list then output to command diplo707 Programming 6 04-23-2012 12:46 PM
Script to read file and copy it to other detination Tekken Programming 5 05-17-2010 12:15 AM
how to read lsof output command many file open by root ??? b-RAM Linux - Newbie 2 10-05-2009 02:40 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 09:42 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration