using awk with find -exec
I have a directory structure with 14 directories containing a bunch of files containing data in a three-column format (separated with tabs). I intended to use find and awk to extract the second column from each of those files and output it with the same filename but under a different root folder. Here the sketch of my directory.
data/all -> AA, AB, AC, AD ... (A* being folders containing the files with data stored in a 3-column format, e.g. AA100.txt, AA101.txt ...)
i want to have the modified (one-column) files with the same name, but all under a new root directory data/pos (as opposed to data/all/) -> AA, AB, AC, AD ... (again, each containing A*100.txt, A*101...)
My try was to use find -exec and to give it the awk command, but I'm having issues with outputting the file to the right place.
when being in data/all/
find * -type f -exec awk '{print$2}' '{}' > ../pos/'{}' ;
However {} as wildcard for the input file doesn't seem to work when outputting the file?
What am I doing wrong? (I'm on a ubuntu server btw)
unix find awk
add a comment |
I have a directory structure with 14 directories containing a bunch of files containing data in a three-column format (separated with tabs). I intended to use find and awk to extract the second column from each of those files and output it with the same filename but under a different root folder. Here the sketch of my directory.
data/all -> AA, AB, AC, AD ... (A* being folders containing the files with data stored in a 3-column format, e.g. AA100.txt, AA101.txt ...)
i want to have the modified (one-column) files with the same name, but all under a new root directory data/pos (as opposed to data/all/) -> AA, AB, AC, AD ... (again, each containing A*100.txt, A*101...)
My try was to use find -exec and to give it the awk command, but I'm having issues with outputting the file to the right place.
when being in data/all/
find * -type f -exec awk '{print$2}' '{}' > ../pos/'{}' ;
However {} as wildcard for the input file doesn't seem to work when outputting the file?
What am I doing wrong? (I'm on a ubuntu server btw)
unix find awk
add a comment |
I have a directory structure with 14 directories containing a bunch of files containing data in a three-column format (separated with tabs). I intended to use find and awk to extract the second column from each of those files and output it with the same filename but under a different root folder. Here the sketch of my directory.
data/all -> AA, AB, AC, AD ... (A* being folders containing the files with data stored in a 3-column format, e.g. AA100.txt, AA101.txt ...)
i want to have the modified (one-column) files with the same name, but all under a new root directory data/pos (as opposed to data/all/) -> AA, AB, AC, AD ... (again, each containing A*100.txt, A*101...)
My try was to use find -exec and to give it the awk command, but I'm having issues with outputting the file to the right place.
when being in data/all/
find * -type f -exec awk '{print$2}' '{}' > ../pos/'{}' ;
However {} as wildcard for the input file doesn't seem to work when outputting the file?
What am I doing wrong? (I'm on a ubuntu server btw)
unix find awk
I have a directory structure with 14 directories containing a bunch of files containing data in a three-column format (separated with tabs). I intended to use find and awk to extract the second column from each of those files and output it with the same filename but under a different root folder. Here the sketch of my directory.
data/all -> AA, AB, AC, AD ... (A* being folders containing the files with data stored in a 3-column format, e.g. AA100.txt, AA101.txt ...)
i want to have the modified (one-column) files with the same name, but all under a new root directory data/pos (as opposed to data/all/) -> AA, AB, AC, AD ... (again, each containing A*100.txt, A*101...)
My try was to use find -exec and to give it the awk command, but I'm having issues with outputting the file to the right place.
when being in data/all/
find * -type f -exec awk '{print$2}' '{}' > ../pos/'{}' ;
However {} as wildcard for the input file doesn't seem to work when outputting the file?
What am I doing wrong? (I'm on a ubuntu server btw)
unix find awk
unix find awk
asked Dec 18 '13 at 13:44
conipoconipo
25114
25114
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
You could try without find, if all you want is all the files. While in data/all/
, run this:
for file in ./*; do awk '{print$2}' "$file" > "../pos/$(basename $file)"; done
If you want to cover the files in the whole hierarchy under /data/all
, you can enable the globstar
option if you are using bash (I believe this would "just work" on zsh) and then use **
to match all files:
shopt -s globstar
for file in ./**; do awk '{print$2}' "$file" > "../pos/$(basename $file)"; done
Usingfor */*
did the trick for me though, the globstar option wasn't available for me.
– conipo
Dec 19 '13 at 19:44
add a comment |
What am I doing wrong?
You are using the redirection > ../pos/'{}'
as if it was handled by find
or awk
but redirections are handled by the shell. In your case it means that you can redirect only output of the whole find
(not output of awk
).
Note that you do not usually need to use wildcard like *
for the starting path of find
. Is the common way find .
what you wanted to do or is there any reason for find *
?
Solutions
Here we will keep the flexibility of find
in contrast to the solution by Jacobo de Vera.
Run awk
in a shell loop:
find . -type f -print0 |
while read -r -d $'' x; do
awk '{print $2}' "$x" > "../pos/$(basename "$x")"
done
The original way with -exec
will be less efficient because for every file a shell will be launched in addition to awk
and the multi-level escaping is pretty complicated here:
find . -type f -exec sh -c 'awk "{print $2}" "{}" > "../pos/{}"' ;
There could also be an alternative solution of doing the redirection inside awk
.
I used the wildcard*
in order to avoid the avoid the./
in the path (as it gave me an error message that it could not find the specified path, which was something likepos/./AA/AA101.txt
-> I had assumed the error to be there, that's why I used the * instead)
– conipo
Dec 19 '13 at 19:42
add a comment |
find /path -exec ls -l {} ; | awk '{print$1}'
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "3"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsuperuser.com%2fquestions%2f690116%2fusing-awk-with-find-exec%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
You could try without find, if all you want is all the files. While in data/all/
, run this:
for file in ./*; do awk '{print$2}' "$file" > "../pos/$(basename $file)"; done
If you want to cover the files in the whole hierarchy under /data/all
, you can enable the globstar
option if you are using bash (I believe this would "just work" on zsh) and then use **
to match all files:
shopt -s globstar
for file in ./**; do awk '{print$2}' "$file" > "../pos/$(basename $file)"; done
Usingfor */*
did the trick for me though, the globstar option wasn't available for me.
– conipo
Dec 19 '13 at 19:44
add a comment |
You could try without find, if all you want is all the files. While in data/all/
, run this:
for file in ./*; do awk '{print$2}' "$file" > "../pos/$(basename $file)"; done
If you want to cover the files in the whole hierarchy under /data/all
, you can enable the globstar
option if you are using bash (I believe this would "just work" on zsh) and then use **
to match all files:
shopt -s globstar
for file in ./**; do awk '{print$2}' "$file" > "../pos/$(basename $file)"; done
Usingfor */*
did the trick for me though, the globstar option wasn't available for me.
– conipo
Dec 19 '13 at 19:44
add a comment |
You could try without find, if all you want is all the files. While in data/all/
, run this:
for file in ./*; do awk '{print$2}' "$file" > "../pos/$(basename $file)"; done
If you want to cover the files in the whole hierarchy under /data/all
, you can enable the globstar
option if you are using bash (I believe this would "just work" on zsh) and then use **
to match all files:
shopt -s globstar
for file in ./**; do awk '{print$2}' "$file" > "../pos/$(basename $file)"; done
You could try without find, if all you want is all the files. While in data/all/
, run this:
for file in ./*; do awk '{print$2}' "$file" > "../pos/$(basename $file)"; done
If you want to cover the files in the whole hierarchy under /data/all
, you can enable the globstar
option if you are using bash (I believe this would "just work" on zsh) and then use **
to match all files:
shopt -s globstar
for file in ./**; do awk '{print$2}' "$file" > "../pos/$(basename $file)"; done
edited Dec 18 '13 at 13:58
answered Dec 18 '13 at 13:50
Jacobo de VeraJacobo de Vera
24217
24217
Usingfor */*
did the trick for me though, the globstar option wasn't available for me.
– conipo
Dec 19 '13 at 19:44
add a comment |
Usingfor */*
did the trick for me though, the globstar option wasn't available for me.
– conipo
Dec 19 '13 at 19:44
Using
for */*
did the trick for me though, the globstar option wasn't available for me.– conipo
Dec 19 '13 at 19:44
Using
for */*
did the trick for me though, the globstar option wasn't available for me.– conipo
Dec 19 '13 at 19:44
add a comment |
What am I doing wrong?
You are using the redirection > ../pos/'{}'
as if it was handled by find
or awk
but redirections are handled by the shell. In your case it means that you can redirect only output of the whole find
(not output of awk
).
Note that you do not usually need to use wildcard like *
for the starting path of find
. Is the common way find .
what you wanted to do or is there any reason for find *
?
Solutions
Here we will keep the flexibility of find
in contrast to the solution by Jacobo de Vera.
Run awk
in a shell loop:
find . -type f -print0 |
while read -r -d $'' x; do
awk '{print $2}' "$x" > "../pos/$(basename "$x")"
done
The original way with -exec
will be less efficient because for every file a shell will be launched in addition to awk
and the multi-level escaping is pretty complicated here:
find . -type f -exec sh -c 'awk "{print $2}" "{}" > "../pos/{}"' ;
There could also be an alternative solution of doing the redirection inside awk
.
I used the wildcard*
in order to avoid the avoid the./
in the path (as it gave me an error message that it could not find the specified path, which was something likepos/./AA/AA101.txt
-> I had assumed the error to be there, that's why I used the * instead)
– conipo
Dec 19 '13 at 19:42
add a comment |
What am I doing wrong?
You are using the redirection > ../pos/'{}'
as if it was handled by find
or awk
but redirections are handled by the shell. In your case it means that you can redirect only output of the whole find
(not output of awk
).
Note that you do not usually need to use wildcard like *
for the starting path of find
. Is the common way find .
what you wanted to do or is there any reason for find *
?
Solutions
Here we will keep the flexibility of find
in contrast to the solution by Jacobo de Vera.
Run awk
in a shell loop:
find . -type f -print0 |
while read -r -d $'' x; do
awk '{print $2}' "$x" > "../pos/$(basename "$x")"
done
The original way with -exec
will be less efficient because for every file a shell will be launched in addition to awk
and the multi-level escaping is pretty complicated here:
find . -type f -exec sh -c 'awk "{print $2}" "{}" > "../pos/{}"' ;
There could also be an alternative solution of doing the redirection inside awk
.
I used the wildcard*
in order to avoid the avoid the./
in the path (as it gave me an error message that it could not find the specified path, which was something likepos/./AA/AA101.txt
-> I had assumed the error to be there, that's why I used the * instead)
– conipo
Dec 19 '13 at 19:42
add a comment |
What am I doing wrong?
You are using the redirection > ../pos/'{}'
as if it was handled by find
or awk
but redirections are handled by the shell. In your case it means that you can redirect only output of the whole find
(not output of awk
).
Note that you do not usually need to use wildcard like *
for the starting path of find
. Is the common way find .
what you wanted to do or is there any reason for find *
?
Solutions
Here we will keep the flexibility of find
in contrast to the solution by Jacobo de Vera.
Run awk
in a shell loop:
find . -type f -print0 |
while read -r -d $'' x; do
awk '{print $2}' "$x" > "../pos/$(basename "$x")"
done
The original way with -exec
will be less efficient because for every file a shell will be launched in addition to awk
and the multi-level escaping is pretty complicated here:
find . -type f -exec sh -c 'awk "{print $2}" "{}" > "../pos/{}"' ;
There could also be an alternative solution of doing the redirection inside awk
.
What am I doing wrong?
You are using the redirection > ../pos/'{}'
as if it was handled by find
or awk
but redirections are handled by the shell. In your case it means that you can redirect only output of the whole find
(not output of awk
).
Note that you do not usually need to use wildcard like *
for the starting path of find
. Is the common way find .
what you wanted to do or is there any reason for find *
?
Solutions
Here we will keep the flexibility of find
in contrast to the solution by Jacobo de Vera.
Run awk
in a shell loop:
find . -type f -print0 |
while read -r -d $'' x; do
awk '{print $2}' "$x" > "../pos/$(basename "$x")"
done
The original way with -exec
will be less efficient because for every file a shell will be launched in addition to awk
and the multi-level escaping is pretty complicated here:
find . -type f -exec sh -c 'awk "{print $2}" "{}" > "../pos/{}"' ;
There could also be an alternative solution of doing the redirection inside awk
.
answered Dec 18 '13 at 15:02
paboukpabouk
4,94853146
4,94853146
I used the wildcard*
in order to avoid the avoid the./
in the path (as it gave me an error message that it could not find the specified path, which was something likepos/./AA/AA101.txt
-> I had assumed the error to be there, that's why I used the * instead)
– conipo
Dec 19 '13 at 19:42
add a comment |
I used the wildcard*
in order to avoid the avoid the./
in the path (as it gave me an error message that it could not find the specified path, which was something likepos/./AA/AA101.txt
-> I had assumed the error to be there, that's why I used the * instead)
– conipo
Dec 19 '13 at 19:42
I used the wildcard
*
in order to avoid the avoid the ./
in the path (as it gave me an error message that it could not find the specified path, which was something like pos/./AA/AA101.txt
-> I had assumed the error to be there, that's why I used the * instead)– conipo
Dec 19 '13 at 19:42
I used the wildcard
*
in order to avoid the avoid the ./
in the path (as it gave me an error message that it could not find the specified path, which was something like pos/./AA/AA101.txt
-> I had assumed the error to be there, that's why I used the * instead)– conipo
Dec 19 '13 at 19:42
add a comment |
find /path -exec ls -l {} ; | awk '{print$1}'
add a comment |
find /path -exec ls -l {} ; | awk '{print$1}'
add a comment |
find /path -exec ls -l {} ; | awk '{print$1}'
find /path -exec ls -l {} ; | awk '{print$1}'
answered Jan 7 at 9:41
mantasmantas
1
1
add a comment |
add a comment |
Thanks for contributing an answer to Super User!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsuperuser.com%2fquestions%2f690116%2fusing-awk-with-find-exec%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown